Java使用wait/notify實現(xiàn)線程間通信下篇
上一節(jié)針對wait/notify實現(xiàn)線程間通信的基本概念做了講解(Java使用wait/notify實現(xiàn)線程間通信上篇),本節(jié)繼續(xù)針對wait/notify實現(xiàn)線程間通信的其他知識點及特性進行講解。
1. 當 interrupt() 方法遇到 wait() 方法
當線程調(diào)用鎖對象的wait() 方法使線程呈等待狀態(tài)時,調(diào)用線程對象的 interrupt() 方法會出現(xiàn) InterruptedException 異常。
public class ThreadC7 { @Test public void test1() { try { Object obj = new Object(); ThreadC7A threadC7A = new ThreadC7A(obj); threadC7A.start(); Thread.sleep(2000); threadC7A.interrupt(); } catch (Exception e) { e.printStackTrace(); } } } class ServiceC7 { public void testMethod(Object obj) { try { synchronized (obj) { System.out.println("begin wait"); obj.wait(); System.out.println("begin end"); } } catch (Exception e) { e.printStackTrace(); System.out.println("出現(xiàn)異常了,wait狀態(tài)的線程被interrupt了!"); } } } class ThreadC7A extends Thread { private Object obj; public ThreadC7A(Object obj) { this.obj = obj; } @Override public void run() { ServiceC7 serviceC7 = new ServiceC7(); serviceC7.testMethod(obj); } }
執(zhí)行結(jié)果:
2. notify() 只通知一個線程
調(diào)用方法notify()一次只隨機通知一個線程進行喚醒。
public class ThreadC8 { @Test public void test() { Object obj = new Object(); ThreadC8A threadC8A = new ThreadC8A(obj); threadC8A.setName("threadC8A"); threadC8A.start(); ThreadC8B threadC8B = new ThreadC8B(obj); threadC8B.setName("threadC8B"); threadC8B.start(); ThreadC8C threadC8C = new ThreadC8C(obj); threadC8C.setName("threadC8C"); threadC8C.start(); try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } synchronized (obj) { obj.notify(); } while (Thread.activeCount() > 1) { } } } class ServiceC8 { public void service(Object obj) { try { synchronized (obj) { String threadName = Thread.currentThread().getName(); System.out.println("begin wait,Thread Name:[" + threadName + "]"); obj.wait(); System.out.println("end wait,Thread Name:[" + threadName + "]"); } } catch (Exception e) { e.printStackTrace(); } } } class ThreadC8A extends Thread { private Object obj; public ThreadC8A(Object obj) { this.obj = obj; } @Override public void run() { ServiceC8 serviceC8 = new ServiceC8(); serviceC8.service(obj); } } class ThreadC8B extends Thread { private Object obj; public ThreadC8B(Object obj) { this.obj = obj; } @Override public void run() { ServiceC8 serviceC8 = new ServiceC8(); serviceC8.service(obj); } } class ThreadC8C extends Thread { private Object obj; public ThreadC8C(Object obj) { this.obj = obj; } @Override public void run() { ServiceC8 serviceC8 = new ServiceC8(); serviceC8.service(obj); } }
執(zhí)行結(jié)果:
程序運行的效果如圖所示,可以看出方法notify()僅隨機喚醒一個線程。
當多次調(diào)用notify()方法時,會隨機將等待wait狀態(tài)的線程進行喚醒。更改代碼如下:
再次運行,程序運行效果如圖所示,可以看出所有的線程全部被喚醒。
多次調(diào)用notify()方法可喚醒全部WAITING中的線程。
3. notifyAll() 喚醒所有線程
前面的示例中通過多次調(diào)用 notify() 方法來實現(xiàn)喚醒3個線程,但并不能保證系統(tǒng)中僅有3個線程,也就是若notify()方法的調(diào)用次數(shù)小于線程對象的數(shù)量,會出現(xiàn)有部分線程對象無法被喚醒的情況。為了喚醒全部線程,可以使用notifyAll()方法。
更改代碼如下:
再次運行,程序運行效果如圖所示,可以看出所有的線程全部被喚醒。
4. 方法 wait(long)的使用
帶一個參數(shù)的wait(long) 方法的功能是等待某一時間內(nèi)是否有現(xiàn)成對鎖進行喚醒,如果超過這個時間則自動喚醒。
public class ThreadC9 { @Test public void test() { Object obj = new Object(); ThreadC9A threadC9A = new ThreadC9A(obj); threadC9A.start(); while (Thread.activeCount() > 1) { } } } class ThreadC9A extends Thread { private Object obj; public ThreadC9A(Object obj) { this.obj = obj; } @Override public void run() { try { synchronized (obj) { long startTime = System.currentTimeMillis(); System.out.println("begin wait,time:[" + startTime + "]"); obj.wait(5000); long endTime = System.currentTimeMillis(); System.out.println("end wait,time:[" + endTime + "] takes " + (endTime - startTime) + " ms"); } } catch (Exception e) { e.printStackTrace(); } } }
執(zhí)行結(jié)果:
通過執(zhí)行結(jié)果可以看出,在經(jīng)過5000ms后,線程被喚醒。
到此這篇關(guān)于Java使用wait/notify實現(xiàn)線程間通信下篇的文章就介紹到這了,更多相關(guān)Java wait notify內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot JPA懶加載失效的解決方案(親測有效)
這篇文章主要介紹了SpringBoot JPA懶加載失效的解決方案(親測有效),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08Java 處理高并發(fā)負載類優(yōu)化方法案例詳解
這篇文章主要介紹了Java 處理高并發(fā)負載類優(yōu)化方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08Java解析http協(xié)議字符串的方法實現(xiàn)
本文主要介紹了Java解析http協(xié)議字符串的方法實現(xiàn),我們探討了如何使用Java解析HTTP協(xié)議字符串,并將其封裝成了一個HttpRequest類,具有一定的參考價值,感興趣的可以了解一下2023-09-09Java數(shù)組優(yōu)點和缺點_動力節(jié)點Java學院整理
本文給大家簡單介紹下java數(shù)組的優(yōu)點和缺點知識,需要的的朋友參考下吧2017-04-04