fucking-java-concurrency
👉 通過Demo示範出Java中并發問題。
🍎 整理Demo的原因
可以觀察到的實際現象
🙈 比 說說的并發原則
🙊 更直覺更可信。
Java語言标準庫支援線程,語言本身(如GC)以及應用(伺服器端The Server side)中會重度使用多線程。
并發程度設計在分析和實作中,複雜度大大增加。 如果不系統了解和充分分析并發邏輯,随意寫代碼,這樣的程式用 『碰巧』 能運作出正确結果 來形容一點都不為過。
這裡的Demo沒有給出解釋和讨論,并且都是入門級的
,更多了解請參見一些并發的問題讨論和資料。
你在開發中碰到的并發問題的例子,歡迎提供(送出Issue)和分享(Fork後送出代碼)!
😘
🍺 無同步的修改在另一個線程中會讀不到
Demo說明
主線程中設定屬性stop為true,以控制在main啟動的任務線程退出。
問題說明
在主線程屬性stop為true後,但任務線程持續運作,即任務線程中一直沒有讀到新值。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.NoPublishDemo
🍺 HashMap的死循環
Demo說明
主線程中開啟2個任務線程執行HashMap的put操作。主線程做get操作。
問題說明
通過沒有持續的輸出判定主線程Block,即HashMap的出現死循環。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.HashMapHangDemo
🍺 組合狀态讀到無效組合
程式設計時,會需要多個狀态記錄(狀态可以是個POJO對象或是int等等)。常看到多狀态讀寫沒有同步的代碼,并且寫的同學會很自然地就忽略了線程安全的問題。
無效組合 是指 從來沒有設定過的組合。
Demo說明
主線程修改多個狀态,為了友善檢查,每次寫入有個固定的關系:第2個狀态是第1個狀态值的2倍。在任務線程中讀取多個狀态。
Demo類com.oldratlee.fucking.concurrency.InvalidCombinationStateDemo。
問題說明
任務線程中讀到了 第2個狀态不是第1個狀态值2倍的值,即是無效值。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.InvalidCombinationStateDemo
🍺 long變量讀到無效值
無效值 是指 從來沒有設定過的值。
Demo說明
主線程修改long變量,為了友善檢查,每次寫入的long值的高4位元組和低4位元組是一樣的。在任務線程中讀取long變量。
問題說明
任務線程中讀到了高4位元組和低4位元組不一樣的long變量,即是無效值。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.InvalidLongDemo
🍺 無同步的并發計數結果不對
Demo說明
主線程中開啟2個任務線程執行并發遞增計數。主線程最終結果檢查。
問題說明
計數值不對。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.WrongCounterDemo
🍺 在易變域上的同步
Demo說明
主線程中開啟2個任務線程執行addListener。主線程最終結果檢查。
問題說明
最終Listener的個數不對。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.SynchronizationOnMutableFieldDemo
🍺 對稱鎖死鎖
Demo說明
主線程中開啟2個任務線程執行。
問題說明
任務線程死鎖。
快速運作
mvn compile exec:java -Dexec.mainClass=com.oldratlee.fucking.concurrency.SymmetricLockDeadlockDemo
一些并發的問題讨論和資料