深入理解執行緒間的通訊方式

2021-10-08 19:08:10 字數 2256 閱讀 4586

等待、通知機制就是,執行緒a呼叫了物件o的wait()方法進入等待狀態,執行緒b 呼叫了物件o的notify()或者notifyall() 喚醒處於物件o上等待的執行緒a,使執行緒a 從wait()方法處返回從而進行剩餘操作。上述兩個執行緒通過物件o來進行互動,而物件o上的wait()/notify()/notifyall()就如同訊號一般控制著執行緒的操作。這種例子生活中隨處可見,例如商品入庫,如果倉庫中是滿的我們就無法將商品再放入倉庫,如果倉庫中沒有商品我們也無法從倉庫中取出商品,再舉乙個日常發生在我們身邊的場景。現在網購越來越方便,我們與快遞之間有乙個快遞小哥在關聯,快遞小哥將包裹放到快遞櫃,我們去快遞櫃領取快遞:

/**

* 快遞

*/public class courier extends thread

couriercabinet.cabinet.add("包裹");

system.out.println("親愛的顧客您的快遞已入櫃,請及時來領取");

couriercabinet.cabinet.notify();

thread.sleep(100);}}

}}

/**

* 收件人

*/public class recipient extends thread

couriercabinet.cabinet.remove("包裹");

system.out.println("哈哈 領到了我的快遞...");

couriercabinet.cabinet.notify();

thread.sleep(100);}}

}}**

* 快遞櫃

*/public class couriercabinet

}

執行結果:

通過以上例子,可以總結出 使用物件的wait()/notify()/notifyall()所要注意的點:

呼叫 wait()/notify()/notifyall() 方法的執行緒必須是持有該物件的鎖的執行緒

呼叫wait()方法後執行緒由running狀態變為waiting狀態,並將當前執行緒放置在該物件的等待佇列中,同時釋放擁有的鎖

呼叫notify()和notifyall()之後執行緒並不會立即從wait()方法處返回,而是需要等待呼叫notify()/notifyall()的執行緒釋放鎖之後才會返回。

notify() 將等待佇列中的執行緒移動到同步佇列中去,notifyall()將等待佇列中所有的執行緒移動到同步佇列中去,此時被移動的執行緒狀態由waiting 轉為blocked

關於執行緒同步、通知機制面試題

1:為什麼操作 wait() notify() notifyall() 需要事先獲取鎖,

主要是為了防止死鎖了永久等待的發生,以上面的例子說明,收件人執行緒執行if(cabinet.size()==0)的時候滿足條件 由於沒有synchronize 加持,所以該執行緒並不一定會執行cabinet.wait() 可能被cpu切走了,執行緒進入了blocked狀態。

此時快遞小哥執行緒獲取到了執行權,判斷if(cabinet.size==10)不滿足條件,然後執行cabinet.add(包裹操作)執行notify()因為收件人執行緒並沒有執行wait(),所以就可能處於一直等待中。就如同你給我打** 我還沒有拿到**你就已經打過了 此時我再拿到**也不會收到你的**了。

wait()放到synchronize 中執行就是為了保證執行緒安全,如果乙個執行緒想要從wait()處返回也需要獲取到該物件的鎖否則會出現illegalmonitorstateexception異常。

3:wait()方法是屬於物件的,那呼叫thread.wait()會怎樣?

呼叫thread.wait() 也就是說將thread 當做鎖物件,持有thread物件的鎖的執行緒在執行結束後會自動呼叫notify(),所以我們應該避免使用執行緒物件來作為鎖物件。

4:notifyall() 會喚醒所有的執行緒同時去爭奪這把鎖,如果沒有獲取到鎖的物件該怎麼辦?

沒有搶到鎖的執行緒會再次進入waiting狀態,進入物件的等待佇列中去,直至有其他執行緒再次呼叫notify()或者notify()all 或者呼叫該執行緒的中斷方法。

程序間通訊的方式?執行緒間通訊的方式?

管道 命名管道 訊號量 訊息佇列 訊號及共享記憶體只適用於本地程序間通訊,套接字則可用於遠端通訊,因而一般用於網路程式設計。部分概念解釋 匿名管道是在快取中開闢的輸出和輸入檔案流的空間,只能用於父子關係的程序之間。因為父子程序的輸入和輸出檔案描述符是一致的。命名管道是一種實際存在的fifo檔案,稱作...

執行緒間通訊方式

執行緒間通訊方式 收藏 執行緒間通訊可以通過下列三種方法 1 使用全域性變數實現執行緒間通訊 2 使用訊息實現執行緒間通訊 3 使用cevent類實現執行緒間通訊 使用全域性變數實現執行緒間通訊 定義乙個全域性變數,不同的執行緒間可以通過修改全域性變數的值來進行通訊。例如 定義乙個控制線程的全域性變...

多執行緒的深入理解

通過單執行緒程式的小例子來深入理解執行緒 程式 執行流程 通過程式執行結果可以看出,主線程建立兩個物件,然後呼叫d1.show 方法,主線程把show方法進棧,執行show方法中的 執行完show方法出棧,此時 d2.show 沒有被執行,緊接著呼叫d2.show 方法。程式執行簡圖 1 多執行緒例...