您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java怎么使用wait或notify實(shí)現(xiàn)線程間通信”,在日常操作中,相信很多人在Java怎么使用wait或notify實(shí)現(xiàn)線程間通信問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java怎么使用wait或notify實(shí)現(xiàn)線程間通信”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
當(dāng)線程調(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é)果:
調(diào)用方法notify()一次只隨機(jī)通知一個線程進(jìn)行喚醒。
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é)果:
程序運(yùn)行的效果如圖所示,可以看出方法notify()僅隨機(jī)喚醒一個線程。
當(dāng)多次調(diào)用notify()方法時,會隨機(jī)將等待wait狀態(tài)的線程進(jìn)行喚醒。更改代碼如下:
再次運(yùn)行,程序運(yùn)行效果如圖所示,可以看出所有的線程全部被喚醒。
多次調(diào)用notify()方法可喚醒全部WAITING中的線程。
前面的示例中通過多次調(diào)用 notify() 方法來實(shí)現(xiàn)喚醒3個線程,但并不能保證系統(tǒng)中僅有3個線程,也就是若notify()方法的調(diào)用次數(shù)小于線程對象的數(shù)量,會出現(xiàn)有部分線程對象無法被喚醒的情況。為了喚醒全部線程,可以使用notifyAll()方法。
更改代碼如下:
再次運(yùn)行,程序運(yùn)行效果如圖所示,可以看出所有的線程全部被喚醒。
帶一個參數(shù)的wait(long) 方法的功能是等待某一時間內(nèi)是否有現(xiàn)成對鎖進(jì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實(shí)現(xiàn)線程間通信”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。