多線程編程中wait()方法拋出IllegalMonitorStateException異常的解析
本文分析一個多線程程序中出現的IllegalMonitorStateException異常,該程序旨在讓三個線程A、B、C依次打印各自ID五次,打印順序為ABCA… 程序使用wait()和notifyAll()方法實現線程同步,但出現異常。
程序錯誤地使用一個volatile修飾的字符串變量current_thread作為鎖對象。每個線程打印前獲取該鎖,但在if-else if-else語句塊中,線程在釋放鎖之前就修改了current_thread的值。這意味著當一個線程調用wait()進入等待時,current_thread指向的對象可能已改變。而wait()方法必須在持有鎖對象的線程上調用,導致后續的notifyAll()嘗試在一個不再持有的鎖對象上釋放鎖,從而引發IllegalMonitorStateException。
問題代碼片段:
// 線程打印完畢后,設置下一個要打印的線程標識,并喚醒其他線程 if (CURRENT_THREAD.equals("A")) { CURRENT_THREAD = "B"; } else if (CURRENT_THREAD.equals("B")) { CURRENT_THREAD = "C"; } else if (CURRENT_THREAD.equals("C")) { CURRENT_THREAD = "A"; }
這段代碼在wait()釋放鎖之前修改了current_thread的引用,導致后續notifyAll()操作失敗。
解決方案:避免在釋放鎖之前修改鎖對象。 應使用獨立的鎖對象控制線程同步,而非直接使用current_thread。引入新的鎖對象,確保修改current_thread之前線程已釋放鎖,避免異常。 正確做法是使用單獨的Object對象作為鎖,在修改current_thread之后再執行notifyAll()操作。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END