1. 程式人生 > >6、多個執行緒的共享資料

6、多個執行緒的共享資料

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