JAVA併發程式設計

2021-08-03 07:50:46 字數 1367 閱讀 7065

通過常量字串 string 來呼叫 wait() 或 notify() 方法所導致的問題是,jvm/編譯器會在內部自動將內容相同的 string 轉變為相同的物件。這意味著,即便你建立了兩個不同的 mywaitnotify 例項,他們內部的 mymonitorobject 變數也會指向相同的 string 物件。這將導致乙個非預期的執行緒中的 notify() 方法會喚醒另睡眠中的執行緒。

2、volatile 關鍵字保證了乙個變數在不同執行緒間的可見性。

3、volatile前提:多個執行緒在讀寫 volatile 變數時新計算並寫入的變數值不依賴於其歷史值,換言之,就是說只要乙個執行緒在寫入乙個 volatile 變數之前不需要先讀取它再計算出新的數值,就不會出現問題。單個寫,不受此限制。

4、由於 volatile 變數的讀寫都要直達主記憶體,而讀寫主記憶體要比讀寫 cpu 的快取更加的費時

5、如果一段**沒持有乙個物件的鎖,就無法呼叫這個物件的 wait(),notif() 或 notifyall() 方法。

6、在一些情況下死鎖的情況是可以被預防的,三種相關的技術 —— 順序鎖(lock ordering)、超時鎖(lock timeout)和死鎖探測(deadlock detection)

順序鎖:死鎖發生在多個執行緒都需要相同的(一系列)鎖,但是所需要的順序不同。如果可以確定任意的執行緒都以相同的順序使用這些鎖,那麼死鎖就不會發生。這種不同的執行緒間通以相同的順序使用鎖來預防死鎖發生的辦法就稱為順序鎖。

順序鎖是乙個簡單但高效的預防死鎖的機制。但其前提是要預先知道所有鎖的執行順序,然而這有時是無法辦到的。

超時鎖:乙個執行緒只會嘗試獲取乙個鎖一段時間,隨後就放棄。如果時限內這個執行緒沒能成功的獲取其本想獲得的全部的鎖,這個執行緒就會備份並釋放掉已經獲得的全部鎖資源,再等待乙個隨機的時長,然後重新從頭開始嘗試。

然而,即便觸發了超時,也不一定意味著發生了死鎖,很可能只是乙個執行緒所處理的任務非常費時。另外一點是,即便引入超時的機制,如果足夠多的執行緒競爭相同的鎖,依舊會使得死鎖的發生概率很高。

死鎖探測:每次乙個執行緒實際獲得乙個鎖時,那麼就在某個資料結構(對映、圖等,你可以自己定義)中做乙個獲得標記;每當乙個執行緒需要獲得乙個鎖時,也將在這個資料結構中做乙個需求標記。如此一來,當乙個執行緒請求乙個鎖但是無法獲得時,這個執行緒就遍歷這個資料結構來探測死鎖。

探測到死鎖後,一種可能的解決方案是所有的執行緒釋放掉所有的鎖,每個等待乙個隨機的時長然後重新嘗試,但問題同上。乙個更好的選擇是為不同的執行緒分配優先順序,使得只有乙個或很少的執行緒釋放掉其持有的鎖資源,而其他的執行緒正常運作。但是如果各個執行緒間的優先順序是確定的話,相同的執行緒可能總是獲得較低的優先順序而無法被執行。為了避免這一情況發生,需要在死鎖發生時隨機分配優先順序。

Java併發程式設計

執行緒之間通訊 1.加鎖 object.wait 釋放鎖 object.notify 與sychronized 聯合使用,object lock new object sychronized lock sychronized lock 2.改進 無需加鎖並發包下 countdownlatch.awa...

Java併發程式設計 分治程式設計

分治演算法是五大常用演算法之一,本來不應該在這個時間寫這篇部落格,因為之前的執行緒池還沒有寫完,有些知識點也是需要用到的執行緒池的,但是架不住現在的專案裡有個坑隊友,名曰大桌球,他好像是批量註冊使用者還是什麼 暫時就先當做是批量註冊吧 反正就是很多很多使用者,每個使用者大概0.5秒左右的註冊時間,要...

Java併發程式設計教程

1 使用執行緒的經驗 設定名稱 響應中斷 使用threadlocal 2 executor executorservice和future 3 阻塞佇列 put和take offer和poll drainto 4 執行緒間的協調手段 lock condition wait notify notifya...