多個線程之間共享數據

多線程共享數據的方式:

 

1,若是每一個線程執行的代碼相同,能夠使用同一個Runnable對象,這個Runnable對象中有那個共享數據,例如,賣票系統,同一件商品的銷售等就能夠這麼作多線程

2,若是每一個線程執行的代碼不一樣,這時候須要用不一樣的Runnable對象,例如,設計4個線程。其中兩個線程每次對j增長1,另外兩個線程對j每次減1,銀行存取款dom

 

有兩種方法來解決此類問題:this

將共享數據封裝成另一個對象,而後將這個對象逐一傳遞給各個Runnable對象,每一個線程對共享數據的操做方法也分配到那個對象身上完成,這樣容易實現針對數據進行各個操做的互斥和通訊spa

將Runnable對象做爲一個類的內部類,共享數據做爲這個類的成員變量,每一個線程對共享數據的操做方法也封裝在外部類,以便實現對數據的各個操做的同步和互斥,做爲內部類的各個Runnable對象調用外部類的這些方法。線程

下面逐一介紹設計

每一個線程執行的代碼相同,能夠使用同一個Runnable對象

賣票系統demo:code

package com.tgb.hjy;  
/** 
 * 多線程共享數據-賣票系統 
 * @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);    
        }    
            
    }    
    
}


 

簡單的多線程間數據共享,每一個線程執行的代碼不一樣,用不一樣的Runnable對象

設計4個線程。

其中兩個線程每次對j增長1,另外兩個線程對j每次減1對象

package com.tgb.hjy;  
  
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);    
    }    
  
}


銀行存取款實例:

package com.tgb.hjy;  
  
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);  
        }  
    }  
}


 

總結:

 

    其實多線程間的共享數據最主要的仍是互斥,多個線程共享一個變量,針對變量的操做實現原子性便可。get

相關文章
相關標籤/搜索