例如:
synchronized關鍵字只是起到了多個執行緒「序列」執行臨界區中**的作用,但是哪個執行緒先執行,哪個執行緒後執行依無法確定,object類中的wait()、notify()和notifyall()三個方法解決了執行緒間的協作問題,通過這三個方法的「合理」使用可以確定多執行緒中線程的先後執行順序:
1、wait():物件鎖呼叫了wait()方法會使當前持有該物件鎖的執行緒處於執行緒等待狀態同時該執行緒釋放對物件鎖的控制權,直到在其他執行緒中該物件鎖呼叫notify()方法或notifyall()方法時等待此物件鎖的執行緒才會被喚醒。
2、notify():物件鎖呼叫notify()方法就會喚醒在此物件鎖上等待的單個執行緒。
3、notifyall():物件鎖呼叫notifyall()方法就會喚醒在此物件鎖上等待的所有執行緒;呼叫notifyall()方法並不會立即啟用某個等待執行緒,它只能撤銷等待執行緒的中斷狀態,這樣它們就能夠在當前執行緒退出同步方法或同步**塊法後與其它執行緒展開競爭,以爭取獲得資源物件來執行。
一句話:誰呼叫了wait方法,誰就必須呼叫notify或notifyall方法,並且「誰」是物件鎖。
使用object類中的wait()、notify()和notifyall()三個方法需要注意以下幾點:
1、wait()方法需要和notify()或notifyall()方法中的乙個配對使用,且wait方法與notify()或notifyall()方法配對使用時不能在同乙個執行緒中(參見**1)。
2、wait()方法、notify()方法和notifyall()方法必須在同步方法或者同步**塊中使用,否則出現illegalmonitorstateexception 異常。
3、呼叫wait()方法、notify()方法和notifyall()方法的物件必須和同步鎖物件是乙個物件。(參見**2)
sleep()方法被呼叫後當前執行緒進入阻塞狀態,但是當前執行緒仍然持有物件鎖,在當前執行緒sleep期間,其它執行緒無法執行sleep方法所在臨界區中的**。
物件鎖呼叫了wait()方法會使當前持有該物件鎖的執行緒處於執行緒等待狀態同時該執行緒釋放對物件鎖的控制權,在當前執行緒處於執行緒等待期間,其它執行緒可以執行wait方法所在臨界區中的**。
儘管此處是死迴圈,但由於物件鎖lockobj呼叫了wait()方法,使得分別持有該lockobj物件鎖的「1號計數器」執行緒和「2號計數器」執行緒處於執行緒等待狀態,所以迴圈並沒有繼續下去
為什麼時間執行緒沒有進入阻塞狀態呢?——timethread變數所代表的物件充當物件鎖,由於該**在main方法中,也就是說將來由主線程執行臨界區中的**,也就是說主線程是持有物件鎖的執行緒,主線程執行完「timethread.wait()」**後進入阻塞狀態,是主線程進入阻塞狀態而非時間執行緒,這也是main方法中「system.out.println("main方法");」**不執行的原因。
儘管左圖藍框裡是死迴圈, 「1號計數器」執行緒和「2號計數器」執行緒輸出1後物件鎖lockobj呼叫了wait()方法,使得兩個執行緒進入執行緒等待狀態;但主線程在sleep 5000毫秒後啟動了notifyallthread執行緒類建立的執行緒物件,該執行緒物件在執行run方法時物件鎖呼叫了notifyall方法,致使兩個執行緒全部被喚醒,所以兩個執行緒又迴圈了一遍
執行緒間的協作同步
幫朋友看時候學了一下這方面知識 有錯誤請糾正 wait notify 和notifyall condition 在condition物件中,與wait,notify和notifyall方法對應的分別是await,signal,signalall。但是,condition對object進行了擴充套件,...
執行緒間的共享和協作
執行緒間的協作 synchroniezd 可以修飾方法或者以同步塊的方式使用。它可以確保多個執行緒在同一時刻,只能有乙個執行緒處於方法或者同步 塊中,保證了執行緒對於變數的訪問的可見性與排他性,又稱之為內鎖機制。物件鎖和類鎖 物件鎖是用於物件例項方法,或者乙個物件例項上的,類鎖是用於類的靜態方法或者...
Java併發程式設計學習 3 執行緒間協作
目錄頁 t.join 方法阻塞呼叫此方法的執行緒 calling thread 直到執行緒t完成,此執行緒再繼續 直接上 package com.concurrent.coline.part3.join 類說明 join方法的使用 public class usejoin override publ...