JAVA 并发编程-多个线程之间共享数据

来源:互联网 发布:ipadmini2网络差 编辑:程序博客网 时间:2024/05/18 01:17

多线程共享数据的方式:

 

1,如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,卖票系统就可以这么做。

2,如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,例如,设计4个线程。其中两个线程每次对j增加1,另外两个线程对j每次减1,银行存取款

 

有两种方法来解决此类问题:

将共享数据封装成另外一个对象,然后将这个对象逐一传递给各个Runnable对象,每个线程对共享数据的操作方法也分配到那个对象身上完成,这样容易实现针对数据进行各个操作的互斥和通信

将Runnable对象作为一个类的内部类,共享数据作为这个类的成员变量,每个线程对共享数据的操作方法也封装在外部类,以便实现对数据的各个操作的同步和互斥,作为内部类的各个Runnable对象调用外部类的这些方法。

 

下面逐一介绍

 

每个线程执行的代码相同,可以使用同一个Runnable对象

 

卖票系统demo


[java] view plain copy
 print?
  1. package com.tgb.hjy;  
  2. /** 
  3.  * 多线程共享数据-卖票系统 
  4.  * @author hejingyuan 
  5.  * 
  6.  */  
  7. public class SellTicket {  
  8.   
  9.      /**  
  10.      * @param args  
  11.      */    
  12.     public static void main(String[] args) {    
  13.         Ticket t = new Ticket();    
  14.         new Thread(t).start();    
  15.         new Thread(t).start();    
  16.     }    
  17. }  
  18. class Ticket implements Runnable{    
  19.         
  20.     private int ticket = 10;    
  21.     public void run() {    
  22.         while(ticket>0){    
  23.             ticket--;    
  24.             System.out.println("当前票数为:"+ticket);    
  25.         }    
  26.             
  27.     }    
  28.     
  29. }   



简单的多线程间数据共享,每个线程执行的代码不同,用不同的Runnable对象

 

设计4个线程。


其中两个线程每次对j增加1,另外两个线程对j每次减1


[java] view plain copy
 print?
  1. package com.tgb.hjy;  
  2.   
  3. public class TestThread {  
  4.   
  5.      /**  
  6.      * @param args  
  7.      */    
  8.     public static void main(String[] args) {    
  9.         final MyData data = new MyData();    
  10.         for(int i=0;i<2;i++){    
  11.             new Thread(new Runnable(){    
  12.     
  13.                 public void run() {    
  14.                     data.add();    
  15.                     
  16.                 }    
  17.                 
  18.             }).start();    
  19.             new Thread(new Runnable(){    
  20.                  
  21.                 public void run() {    
  22.                     data.dec();    
  23.                     
  24.                 }    
  25.                 
  26.             }).start();    
  27.         }    
  28.     }    
  29.     
  30. }  
  31.   
  32. class MyData {    
  33.     private int j=0;    
  34.     public  synchronized void add(){    
  35.         j++;    
  36.         System.out.println("线程"+Thread.currentThread().getName()+"j为:"+j);    
  37.     }    
  38.     public  synchronized void dec(){    
  39.         j--;    
  40.         System.out.println("线程"+Thread.currentThread().getName()+"j为:"+j);    
  41.     }    
  42.   
  43. }    



银行存取款实例:


[java] view plain copy
 print?
  1. package com.tgb.hjy;  
  2.   
  3. public class Acount {  
  4.   
  5.      private int money;  
  6.      public Acount(int money){  
  7.        this.money=money;  
  8.      }  
  9.        
  10.      public synchronized void getMoney(int money){  
  11.       //注意这个地方必须用while循环,因为即便再存入钱也有可能比取的要少  
  12.       while(this.money<money){           
  13.            System.out.println("取款:"+money+" 余额:"+this.money+" 余额不足,正在等待存款......");  
  14.            try{ wait();} catch(Exception e){}  
  15.       }  
  16.       this.money=this.money-money;  
  17.       System.out.println("取出:"+money+" 还剩余:"+this.money);  
  18.        
  19.      }  
  20.        
  21.      public synchronized void setMoney(int money){  
  22.        
  23.       try{ Thread.sleep(10);}catch(Exception e){}  
  24.       this.money=this.money+money;  
  25.       System.out.println("新存入:"+money+" 共计:"+this.money);  
  26.       notify();  
  27.      }  
  28.        
  29.      public static void main(String args[]){  
  30.           Acount Acount=new Acount(0);  
  31.           Bank b=new Bank(Acount);  
  32.           Consumer c=new Consumer(Acount);  
  33.           new Thread(b).start();  
  34.           new Thread(c).start();  
  35.      }  
  36. }  
  37. //存款类  
  38. class Bank implements Runnable {  
  39.         Acount Acount;  
  40.         public Bank(Acount Acount){  
  41.             this.Acount=Acount;  
  42.         }  
  43.         public void run(){  
  44.             while(true){  
  45.                  int temp=(int)(Math.random()*1000);  
  46.                  Acount.setMoney(temp);    
  47.     }  
  48. }  
  49.   
  50. }  
  51. //取款类  
  52. class Consumer implements Runnable {  
  53.         Acount Acount;  
  54.         public Consumer(Acount Acount){  
  55.             this.Acount=Acount;  
  56.         }  
  57.         public void run(){  
  58.         while(true){           
  59.             int temp=(int)(Math.random()*1000);  
  60.             Acount.getMoney(temp);  
  61.         }  
  62.     }  
  63. }  




总结:


    其实多线程间的共享数据最主要的还是互斥,多个线程共享一个变量,针对变量的操作实现原子性即可。

阅读全文
0 0