分享

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

 跑不动的猪 2020-05-05

多线程共享数据的方式:

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

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

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

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

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

}

}

}

总结:

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多