zoukankan      html  css  js  c++  java
  • JAVA 并发编程-多个线程之间共享数据(六)


    多线程共享数据的方式:

     

    1。假设每一个线程运行的代码同样。能够使用同一个Runnable对象,这个Runnable对象中有那个共享数据,比如,卖票系统就能够这么做。

    2,假设每一个线程运行的代码不同。这时候须要用不同的Runnable对象,比如,设计4个线程。

    当中两个线程每次对j添加1。另外两个线程对j每次减1。银行存取款

     

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

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

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

     

    以下逐一介绍

     

    每一个线程运行的代码同样,能够使用同一个Runnable对象

     

    卖票系统demo


    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);
    		}
    	}
    }




    总结:


        事实上多线程间的共享数据最基本的还是相互排斥,多个线程共享一个变量,针对变量的操作实现原子性就可以。




  • 相关阅读:
    答题技巧总结(高项)
    系统集成 中英文对照 第一季
    系统集成管理项目工程师总结(别人发的 )
    系统集成管理项目工程师总结(别人发的 我觉得很有意思)
    熵、信息增益以及其他
    位运算
    二分查找排序
    在链表中漫游
    Levenshtein距离
    动态规划(dynamic programming)
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7293940.html
Copyright © 2011-2022 走看看