日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > Java并發(fā)編程的藝術(shù)(六)——線程間的通信

Java并發(fā)編程的藝術(shù)(六)——線程間的通信

來源:程序員人生   發(fā)布時(shí)間:2018-06-11 17:28:16 閱讀次數(shù):10080次

多條線程之間有時(shí)需要數(shù)據(jù)交互,下面介紹5種線程間數(shù)據(jù)交互的方式,他們的使用處景各有不同。

1. volatile、synchronized關(guān)鍵字

PS:關(guān)于volatile的詳細(xì)介紹請(qǐng)移步至:Java并發(fā)編程的藝術(shù)(3)——volatile

1.1 如何實(shí)現(xiàn)通訊?

這兩種方式都采取了同步機(jī)制實(shí)現(xiàn)多條線程間的數(shù)據(jù)通訊。與其說是“通訊”,倒不如說是“同享變量”來的恰當(dāng)。當(dāng)1個(gè)同享變量被volatile修飾 或 被同步塊包裹后,他們的讀寫操作都會(huì)直接操作同享內(nèi)存,從而各個(gè)線程都能看到同享變量最新的值,也就是實(shí)現(xiàn)了內(nèi)存的可見性。

1.2 特點(diǎn)

  • 這類方式本質(zhì)上是“同享數(shù)據(jù)”,而非“傳遞數(shù)據(jù)”;只是從結(jié)果來看,數(shù)據(jù)好像是從寫線程傳遞到了讀線程;
  • 這類通訊方式?jīng)]法指定特定的接收線程。當(dāng)數(shù)據(jù)被修改后究竟哪條線程最早訪問到,這由操作系統(tǒng)隨機(jī)決定。
  • 總的來講,這類方式其實(shí)不是真正意義上的“通訊”,而是“同享”。

1.3 使用處景

這類方式能“傳遞”變量。當(dāng)需要傳遞1些公用的變量時(shí)就能夠使用這類方式。如:傳遞boolean flag,用于表示狀態(tài)、傳遞1個(gè)存儲(chǔ)所有任務(wù)的隊(duì)列等。

1.4 例子

用這類方式實(shí)現(xiàn)線程的開關(guān)控制。

// 用于控制線程當(dāng)前的履行狀態(tài) private volatile boolean running = false; // 開啟1條線程 Thread thread = new Thread(new Runnable(){ void run(){ // 開關(guān) while(!running){
            Thread.sleep(1000);
        } // 履行線程任務(wù) doSometing();
    }
}).start(); // 開始履行 public void start(){
    running = true;
}

2. 等待/通知機(jī)制

2.1 如何實(shí)現(xiàn)?

等待/通知機(jī)制的實(shí)現(xiàn)由Java完成,我們只需調(diào)用Object類的幾個(gè)方法便可。

  • wait():將當(dāng)前線程的狀態(tài)改成“等待態(tài)”,加入等待隊(duì)列,釋放鎖;直到當(dāng)前線程產(chǎn)生中斷或調(diào)用了notify方法,這條線程才會(huì)被從等待隊(duì)列轉(zhuǎn)移到同步隊(duì)列,此時(shí)可以開始競(jìng)爭(zhēng)鎖。
  • wait(long):和wait()功能1樣,只不過量了個(gè)超時(shí)動(dòng)作。1旦超時(shí),就會(huì)繼續(xù)履行wait以后的代碼,它不會(huì)拋超時(shí)異常!
  • notify():將等待隊(duì)列中的1條線程轉(zhuǎn)移到同步隊(duì)列中去。
  • notifyAll():將等待隊(duì)列中的所有線程都轉(zhuǎn)移到同步隊(duì)列中去。

2.2 注意點(diǎn)

  • 以上方法都必須放在同步塊中;
  • 并且以上方法都只能由所處同步塊的鎖對(duì)象調(diào)用;
  • 鎖對(duì)象A.notify()/notifyAll()只能喚醒由鎖對(duì)象A wait的線程;
  • 調(diào)用notify/notifyAll函數(shù)后僅僅是將線程從等待隊(duì)列轉(zhuǎn)移到阻塞隊(duì)列,只有當(dāng)該線程競(jìng)爭(zhēng)到鎖后,才能從wait方法中返回,繼續(xù)履行接下來的代碼;

2.3 QA

  • 為何wait必須放在同步塊中調(diào)用?
    由于等待/通知機(jī)制需要和同享狀態(tài)變量配合使用,1般是先檢查狀態(tài),若狀態(tài)為true則履行wait,即包括“先檢查后履行”,因此需要把這1進(jìn)程加鎖,確保其原子履行。
    舉個(gè)例子:
// 同享的狀態(tài)變量 boolean flag = false; // 線程1 Thread t1 = new Thread(new Runnable(){ public void run(){ while(!flag){
            wait();
        }
    }
}).start(); // 線程2 Thread t2 = new Thread(new Runnable(){ public void run(){
        flag = true;
        notifyAll();
    }
}).start();

上述例子thread1未加同步。當(dāng)thread1履行到while那行后,判斷其狀態(tài)為true,此時(shí)若產(chǎn)生上下文切換,線程2開始履行,并1口氣履行完了;此時(shí)flag已是true,但是thread1繼續(xù)履行,遇到wait后便進(jìn)入等待態(tài);但此時(shí)已沒有線程能喚醒它了,因此就1直等待下去。

  • 為何notify需要加鎖?且必須和wait使用同1把鎖?
    首先,加鎖是為了保證同享變量的內(nèi)存可見性,讓它產(chǎn)生修改后能直接寫入同享內(nèi)存,好讓wait所處的線程立即看見。
    其次,和wait使用同1把鎖是為了確保wait、notify之間的互斥,即:同1時(shí)刻,只能有其中1條線程履行。

  • 為何必須使用同步塊的鎖對(duì)象調(diào)用wait函數(shù)?
    首先,由于wait會(huì)釋放鎖,因此通過鎖對(duì)象調(diào)用wait就是告知wait釋放哪一個(gè)鎖。
    其次,告知線程,你是在哪一個(gè)鎖對(duì)象上等待的,只有當(dāng)該鎖對(duì)象調(diào)用notify時(shí)你才能被喚醒。

  • 為何必須使用同步塊的鎖對(duì)象調(diào)用notify函數(shù)?
    告知notify,只喚醒在該鎖對(duì)象上等待的線程。

2.4 代碼實(shí)現(xiàn)

等待/通知機(jī)制用于實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者模式。

  • 生產(chǎn)者
synchronized(鎖A){
    flag = true;// 或:list.add(xx); 鎖A.notify();
}
  • 消費(fèi)者
synchronized(鎖A){ // 不滿足條件 while(!flag){ // 或:list.isEmpty() 鎖A.wait();
    } // doSometing…… }

2.5 超時(shí)等待模式

在之前的生產(chǎn)者-消費(fèi)者模式中,如果生產(chǎn)者沒有發(fā)出通知,那末消費(fèi)者將永久等待下去。為了不這類情況,我們可以給消費(fèi)者增加超時(shí)等待功能。該功能依托于wait(long)方法,只需在wait前的檢查條件中增加超時(shí)標(biāo)識(shí)位,實(shí)現(xiàn)以下:

public void get(long mills){
    synchronized( list ){ // 不加超時(shí)功能 if ( mills <= 0 ) { while( list.isEmpty() ){ list.wait();
            }
        } // 添加超時(shí)功能 else {
            boolean isTimeout = false; while(list.isEmpty() && isTimeout){ list.wait(mills);
                isTimeout = true;
            } // doSometing…… }
    }
}

3. 管道流

3.1 作用

管道流用于在兩個(gè)線程之間進(jìn)行字節(jié)流或字符流的傳遞。

3.2 特點(diǎn)

  • 管道流的實(shí)現(xiàn)依托PipedOutputStream、PipedInputStream、PipedWriter、PipedReader。分別對(duì)應(yīng)字節(jié)流和字符流。
  • 他們與IO流的區(qū)分是:IO流是在硬盤、內(nèi)存、Socket之間活動(dòng),而管道流僅在內(nèi)存中的兩條線程間活動(dòng)。

3.3 實(shí)現(xiàn)

步驟以下:
1. 在1條線程中分別創(chuàng)建輸入流和輸出流;
2. 將輸入流和輸出留連接起來;
3. 將輸入流和輸出流分外傳遞給兩條線程;
4. 調(diào)用read和write方法就能夠?qū)崿F(xiàn)線程間通訊。

// 創(chuàng)建輸入流與輸出流對(duì)象 PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader(); // 連接輸入輸出流 out.connect(in); // 創(chuàng)建寫線程 class WriteThread extends Thread{ private PipedWriter out; public WriteThread(PipedWriter out){ this.out = out;
    } public void run(){
        out.write("hello concurrent world!");
    }
} // 創(chuàng)建讀線程 class ReaderThread extends Thread{ private PipedReader in; public ReaderThread(PipedReader in){ this.in = in;
    } public void run(){
        in.read();
    }
} // 

4. join

4.1 作用

  • join能將并發(fā)履行的多條線程串行履行;
  • join函數(shù)屬于Thread類,通過1個(gè)thread對(duì)象調(diào)用。當(dāng)在線程B中履行threadA.join()時(shí),線程B將會(huì)被阻塞(底層調(diào)用wait方法),等到threadA線程運(yùn)行結(jié)束后才會(huì)返回join方法。
  • 被等待的那條線程可能會(huì)履行很長(zhǎng)時(shí)間,因此join函數(shù)會(huì)拋出InterruptedException。當(dāng)調(diào)用threadA.interrupt()后,join函數(shù)就會(huì)拋出該異常。

4.2 實(shí)現(xiàn)

public static void main(String[] args){ // 開啟1條線程 Thread t = new Thread(new Runnable(){ public void run(){ // doSometing }
    }).start(); // 調(diào)用join,等待t線程履行終了 try{
        t.join();
    }catch(InterruptedException e){ // 中斷處理…… }

}


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 婷婷综合五月 | 不卡视频一区二区 | 91成人国产 | 综合久久一区 | 日日噜噜噜夜夜狠狠久久蜜桃 | 亚洲国产精品久久 | 亚洲美女av在线 | 91精产品一区一区三区 | 日韩黄色片 | 日韩国产精品视频 | 国产精品一区二区三区四区五区 | 欧美激情精品久久久久久变态 | 国产欧美日韩中文字幕 | 国产精品亚洲一区 | 在线看中文字幕 | 日韩欧美在线一区二区 | 99在线精品视频 | 在线不卡一区二区 | 日韩视频一区二区 | 成年人视频在线免费观看 | 中国成人免费视频 | 日韩久久激情 | 久久精品视频一区 | 精品1区2区| 99国产一区 | 亚洲视频在线一区二区 | 精品一区二区三区免费 | 日韩欧美一区二区三区在线视频 | 久久久久久91 | 久久久精品在线 | 久久久久夜夜夜精品国产 | 国产真实精品久久二三区 | 性欧美xxxx | 久久久久久久久久久久久久久久久久久久 | 亚洲精品国产综合区久久久久久久 | 国产精品久久久久久久免费软件 | 日韩欧美精品区 | 国产精品一区二区在线播放 | 激情中文字幕 | 国产.com| 午夜黄色av |