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

    xiaoxiao2026-04-02  6

    多线程共享数据的方式:

     

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

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

     

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

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

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

     

    下面逐一介绍

     

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

     

    卖票系统demo

    [java] view plain copy print ? 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

    [java] view plain copy print ? 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);        }      }    

    银行存取款实例:

    [java] view plain copy print ? 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);          }      }  }  

    总结:

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

    转载请注明原文地址: https://ju.6miu.com/read-1308429.html
    最新回复(0)