2 回答

TA貢獻1777條經驗 獲得超3個贊
我不認為這是一個騙局,因為盡管有標題,但實際問題是 OP 的具體實現。代碼中有一個錯誤,這不是方法與塊的問題。
代碼中的錯誤是您嘗試實現鎖定機制的地方。在incr()中,您等到available設置為 false,這僅發生在getVal():
public synchronized void incr() {
while (available) { // <-- bug
try {
wait();
由于您的循環只調用incr()而不調用getVal(),因此兩個線程在第一次調用incr(). (你getVal()最終會調用,但只有在內循環完成之后。兩個線程都很好并且到那時卡住了。)
解決方案:AtomicInteger沒有像這樣的奇怪錯誤。如果您嘗試實現某種生產者/消費者機制,那么其中一個并發隊列(如ArrayBlockingQueue)是更好的解決方案。

TA貢獻1909條經驗 獲得超7個贊
同步方法和塊之間的一個顯著區別是,同步塊通常會減少鎖定范圍。由于鎖定范圍與性能成反比,因此只鎖定代碼的關鍵部分總是更好。使用同步塊的最佳示例之一是 Singleton 模式中的雙重檢查鎖定,
getInstance()
我們只鎖定用于創建 Singleton 實例的代碼的關鍵部分,而不是鎖定整個方法。這極大地提高了性能,因為鎖定只需要一兩次。同步塊提供了對鎖的精細控制,因為您可以使用任意鎖來為關鍵部分代碼提供互斥。另一方面,同步方法總是鎖定由 this 關鍵字表示的當前對象或類級別鎖定,如果它的靜態同步方法。
如果作為參數提供給塊的表達式計算為 null,則同步塊可以拋出 throw
java.lang.NullPointerException
,而同步方法則不是這種情況。在同步方法的情況下,線程進入方法時獲取鎖,離開方法時釋放鎖,正?;驋伋霎惓?。另一方面,在同步塊的情況下,線程進入同步塊時獲取鎖,離開同步塊時釋放。
添加回答
舉報