6、多個執行緒的共享資料
阿新 • • 發佈:2019-01-28
1、方式
1,如果每個執行緒執行的程式碼相同,可以使用同一個Runnable物件,這個Runnable物件中有那個共享資料,例如,賣票系統就可以這麼做。
2,如果每個執行緒執行的程式碼不同,這時候需要用不同的Runnable物件,例如,設計4個執行緒。其中兩個執行緒每次對j增加1,另外兩個執行緒對j每次減1,銀行存取款
賣票系統:
package cn.itcast.thread;
/**
* 多執行緒共享資料-賣票系統
* @author hejingyuan
*
*/
public class SellTicket {
/**
* @param args
*/
public static void main(String[] args) {
Ticket t = new Ticket();
new Thread(t).start();
new Thread(t).start();
}
}
class Ticket implements Runnable{
private int ticket = 10;
public void run() {
while(ticket>0){
ticket--;
System.out.println("當前票數為:"+ticket);
}
}
}
結果:
當前票數為:9 當前票數為:8 當前票數為:7 當前票數為:6 當前票數為:5 當前票數為:4 當前票數為:3 當前票數為:2 當前票數為:1 當前票數為:0
簡單的多執行緒間資料共享,每個執行緒執行的程式碼不同,用不同的Runnable物件
package cn.itcast.thread;
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
final MyData data = new MyData();
for(int i=0;i<2;i++){
new Thread(new Runnable(){
public void run() {
data.add();
}
}).start();
new Thread(new Runnable(){
public void run() {
data.dec();
}
}).start();
}
}
}
class MyData {
private int j=0;
public synchronized void add(){
j++;
System.out.println("執行緒"+Thread.currentThread().getName()+"j為:"+j);
}
public synchronized void dec(){
j--;
System.out.println("執行緒"+Thread.currentThread().getName()+"j為:"+j);
}
}
執行緒Thread-0j為:1
執行緒Thread-1j為:0
執行緒Thread-2j為:1
執行緒Thread-3j為:0
銀行存取款例項:
package cn.itcast.thread;
public class Acount {
private int money;
public Acount(int money){
this.money=money;
}
public synchronized void getMoney(int money){
//注意這個地方必須用while迴圈,因為即便再存入錢也有可能比取的要少
while(this.money<money){
System.out.println("取款:"+money+" 餘額:"+this.money+" 餘額不足,正在等待存款......");
try{ wait();} catch(Exception e){}
}
this.money=this.money-money;
System.out.println("取出:"+money+" 還剩餘:"+this.money);
}
public synchronized void setMoney(int money){
try{ Thread.sleep(10);}catch(Exception e){}
this.money=this.money+money;
System.out.println("新存入:"+money+" 共計:"+this.money);
notify();
}
public static void main(String args[]){
Acount Acount=new Acount(0);
Bank b=new Bank(Acount);
Consumer c=new Consumer(Acount);
new Thread(b).start();
new Thread(c).start();
}
}
//存款類
class Bank implements Runnable {
Acount Acount;
public Bank(Acount Acount){
this.Acount=Acount;
}
public void run(){
while(true){
int temp=(int)(Math.random()*1000);
Acount.setMoney(temp);
}
}
}
//取款類
class Consumer implements Runnable {
Acount Acount;
public Consumer(Acount Acount){
this.Acount=Acount;
}
public void run(){
while(true){
int temp=(int)(Math.random()*1000);
Acount.getMoney(temp);
}
}
}
新存入:849 共計:849
取款:865 餘額:849 餘額不足,正在等待存款......
新存入:95 共計:944
取出:865 還剩餘:79
新存入:825 共計:904
取出:874 還剩餘:30
新存入:533 共計:563
取款:865 餘額:563 餘額不足,正在等待存款......
新存入:71 共計:634
取款:865 餘額:634 餘額不足,正在等待存款......
新存入:606 共計:1240
取出:865 還剩餘:375
取款:801 餘額:375 餘額不足,正在等待存款......
新存入:868 共計:1243