JAVA 線程通信相關(guān)知識(shí)匯總
兩個(gè)線程之間的通信
多線程環(huán)境下CPU會(huì)隨機(jī)的在線程之間進(jìn)行切換,如果想讓兩個(gè)線程有規(guī)律的去執(zhí)行,那就需要兩個(gè)線程之間進(jìn)行通信,在Object類中的兩個(gè)方法wait和notify可以實(shí)現(xiàn)通信。
wait方法可以使當(dāng)前線程進(jìn)入到等待狀態(tài),在沒(méi)有被喚醒的情況下,線程會(huì)一直保持等待狀態(tài)。
notify方法可以隨機(jī)喚醒單個(gè)在等待狀態(tài)下的線程。
來(lái)實(shí)現(xiàn)這樣的一個(gè)功能:
讓兩個(gè)線程交替在控制臺(tái)輸出一行文字
定義一個(gè)Print類,有兩個(gè)方法print1和print2,分別打印一行不同的內(nèi)容
package com.sutaoyu.volatlt; public class Print { private int flag = 1; public void print1() { synchronized(this) { if(flag != 1) { try { //讓當(dāng)前線程進(jìn)入等入狀態(tài) this.wait(); }catch(InterruptedException e) { e.printStackTrace(); } } System.out.println("monkey"); flag = 2; //隨機(jī)的喚醒單個(gè)等待的線程 this.notify(); } } public void print2() { synchronized(this) { if(flag != 2) { try { this.wait(); }catch (InterruptedException e){ e.printStackTrace(); } } System.out.println("1024"); flag = 1; this.notify(); } } }
定義線程測(cè)試類,開(kāi)啟兩個(gè)線程,分別運(yùn)行Print類中print1和print2方法
package com.sutaoyu.volatlt; public class NotifyTest01 { public static void main(String[] args) { Print p = new Print(); Thread t1 = new Thread() { public void run() { while(true) { p.print1(); } } }; Thread t2 = new Thread() { public void run() { while(true) { p.print2(); } } }; t1.start(); t2.start(); } }
三個(gè)及三個(gè)以上的線程之間的通信
改造上面代碼在Print類中添加一個(gè)print3方法,再開(kāi)啟第三個(gè)線程來(lái)執(zhí)行這個(gè)方法。
另外需要修改的地方是:
1.因?yàn)閚otifyAll方法可以喚醒所有等待狀態(tài)的線程,所有用notifyAll方法來(lái)替代notify方法
2.當(dāng)線程被喚醒后,需要先判斷一下flag的值,if不會(huì)重新判斷flag值,而while會(huì)重新判斷flag的值,所以將Print中的if判斷修改為while判斷。
package com.sutaoyu.volatlt; public class Print { private int flag = 1; public void print1() { synchronized(this) { while(flag != 1) { try { //讓當(dāng)前線程進(jìn)入等入狀態(tài) this.wait(); }catch(InterruptedException e) { e.printStackTrace(); } } System.out.println("monkey"); flag = 2; //隨機(jī)的喚醒單個(gè)等待的線程 this.notifyAll(); } } public void print2() { synchronized(this) { while(flag != 2) { try { this.wait(); }catch (InterruptedException e){ e.printStackTrace(); } } System.out.println("1024"); flag = 3; this.notifyAll(); } } public void print3() { synchronized(this) { while(flag != 3) { try { this.wait(); }catch(InterruptedException e) { e.printStackTrace(); } } System.out.println("888"); flag = 1; this.notifyAll(); } } }
package com.sutaoyu.volatlt; public class NotifyTest01 { public static void main(String[] args) { Print p = new Print(); Thread t1 = new Thread() { public void run() { while(true) { p.print1(); } } }; Thread t2 = new Thread() { public void run() { while(true) { p.print2(); } } }; Thread t3 = new Thread() { public void run() { while(true) { p.print3(); } } }; t1.start(); t2.start(); t3.start(); } }
線程通信注意事項(xiàng)
在print1,2,3方法中同步代碼塊中使用哪個(gè)對(duì)象作為鎖,那在調(diào)用wait和notify方法時(shí)一定要調(diào)用這個(gè)對(duì)象上的wait和notify方法。
上面程序使用this作為對(duì)象鎖,在下面調(diào)用的都是this.wait()和this.notify()方法。
在多線程執(zhí)行當(dāng)中
wait方法釋放對(duì)象鎖,根據(jù)上面的代碼示例,t1,t2,t3三個(gè)線程使用的是同一個(gè)對(duì)象鎖,如果wait方法不釋放鎖的話,別的線程就不能獲取到該鎖,也就不能獲取cpu的執(zhí)行權(quán)了。
sleep和notify方法不釋放對(duì)象鎖,上面代碼示例中,如果notify方法釋放鎖的話,別的線程就有可能獲取到cpu的執(zhí)行權(quán),這樣子就會(huì)導(dǎo)致當(dāng)前notify方法后面的代碼還未執(zhí)行完畢就失去了cpu的執(zhí)行權(quán),從而導(dǎo)致一些問(wèn)題,只有當(dāng)線程執(zhí)行完synchronized代碼塊后才會(huì)釋放鎖。
以上就是JAVA 線程通信相關(guān)知識(shí)匯總的詳細(xì)內(nèi)容,更多關(guān)于JAVA 線程通信的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java實(shí)現(xiàn)兩人五子棋游戲(三) 畫(huà)出棋子
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)兩人五子棋游戲,畫(huà)出五子棋的棋子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03spring啟動(dòng)錯(cuò)誤Singleton bean creation not al
本文主要介紹了spring啟動(dòng)錯(cuò)誤Singleton bean creation not allowed while the singletons of this factory are indestruction,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07java實(shí)現(xiàn)簡(jiǎn)單租車系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單租車系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01springboot?filter配置多個(gè)時(shí),執(zhí)行順序問(wèn)題
這篇文章主要介紹了springboot?filter配置多個(gè)時(shí),執(zhí)行順序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12實(shí)例分析Java Class的文件結(jié)構(gòu)
今天把之前在Evernote中的筆記重新整理了一下,發(fā)上來(lái)供對(duì)java class 文件結(jié)構(gòu)的有興趣的同學(xué)參考一下2013-04-04JavaWeb倉(cāng)庫(kù)管理系統(tǒng)詳解
這篇文章主要為大家詳細(xì)介紹了JavaWeb倉(cāng)庫(kù)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09