日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JAVA 并發(fā)編程-多個線程之間共享數(shù)據(jù)(六)

 跑不動的豬 2020-05-05

多線程共享數(shù)據(jù)的方式:

1,如果每個線程執(zhí)行的代碼相同,可以使用同一個Runnable對象,這個Runnable對象中有那個共享數(shù)據(jù),例如,賣票系統(tǒng)就可以這么做。

2,如果每個線程執(zhí)行的代碼不同,這時候需要用不同的Runnable對象,例如,設(shè)計(jì)4個線程。其中兩個線程每次對j增加1,另外兩個線程對j每次減1,銀行存取款

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

將共享數(shù)據(jù)封裝成另外一個對象,然后將這個對象逐一傳遞給各個Runnable對象,每個線程對共享數(shù)據(jù)的操作方法也分配到那個對象身上完成,這樣容易實(shí)現(xiàn)針對數(shù)據(jù)進(jìn)行各個操作的互斥和通信

將Runnable對象作為一個類的內(nèi)部類,共享數(shù)據(jù)作為這個類的成員變量,每個線程對共享數(shù)據(jù)的操作方法也封裝在外部類,以便實(shí)現(xiàn)對數(shù)據(jù)的各個操作的同步和互斥,作為內(nèi)部類的各個Runnable對象調(diào)用外部類的這些方法。

下面逐一介紹

每個線程執(zhí)行的代碼相同,可以使用同一個Runnable對象

賣票系統(tǒng)demo:

package com.tgb.hjy;

/**

 * 多線程共享數(shù)據(jù)-賣票系統(tǒng)

 * @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("當(dāng)前票數(shù)為:"+ticket);  

        }  

    }  

簡單的多線程間數(shù)據(jù)共享,每個線程執(zhí)行的代碼不同,用不同的Runnable對象

設(shè)計(jì)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);  

    }  

}  

銀行存取款實(shí)例:

package com.tgb.hjy;

public class Acount {

private int money;

public Acount(int money){

   this.money=money;

}

public synchronized void getMoney(int money){

  //注意這個地方必須用while循環(huán),因?yàn)榧幢阍俅嫒脲X也有可能比取的要少

  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+" 共計(jì):"+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);

}

}

}

總結(jié):

    其實(shí)多線程間的共享數(shù)據(jù)最主要的還是互斥,多個線程共享一個變量,針對變量的操作實(shí)現(xiàn)原子性即可。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多