在Java中,join()和wait()都是用于線程間通信的方法,但它們的實現(xiàn)機制、作用和用法有所不同。
首先來看一下join()方法。當一個線程A執(zhí)行了t.join()代碼后,它會等待線程t執(zhí)行完畢后再繼續(xù)執(zhí)行。這就像是在等待一個子線程的結束,類似于main線程等待所有子線程結束后再退出。加入join()方法可以讓線程之間的順序執(zhí)行更加有序。
Thread t = new Thread(() ->{ System.out.println("線程t開始執(zhí)行"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程t執(zhí)行完畢"); }); t.start(); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("主線程執(zhí)行完畢");
接下來再看一下wait()方法。當一個線程執(zhí)行了obj.wait()代碼后,它會進入對象obj的等待隊列并釋放該對象的鎖,進入等待狀態(tài)。當其他線程執(zhí)行obj.notify()或obj.notifyAll()時,就會在等待隊列中隨機選擇一個線程喚醒,使其重新競爭該對象的鎖并繼續(xù)執(zhí)行。
Object obj = new Object(); Thread t1 = new Thread(() ->{ synchronized (obj) { System.out.println("線程t1獲取了對象obj的鎖,并開始執(zhí)行"); try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程t1被喚醒,重新獲取了對象obj的鎖并繼續(xù)執(zhí)行"); } }); Thread t2 = new Thread(() ->{ synchronized (obj) { System.out.println("線程t2獲取了對象obj的鎖,并開始執(zhí)行"); obj.notify(); } }); t1.start(); t2.start();
總結一下,join()方法是讓一個線程等待另一個線程執(zhí)行完畢后再繼續(xù)執(zhí)行,而wait()方法是讓線程等待某個條件的發(fā)生。不同點在于join()是等待單個線程結束,wait()是等待某個條件滿足。同時,wait()方法需要在synchronized塊中使用,因為它會釋放鎖。