Java多線程編程:對象鎖與類鎖在synchronized塊中的正確使用方法
本文分析一個java多線程編程案例,闡述synchronized關鍵字在對象鎖和類鎖下的不同行為,并解釋IllegalMonitorStateException異常的產生原因。
案例中,兩個線程并發訪問Printer_1打印機對象,Printer_1類實現了Runnable接口,其run方法模擬打印0到100的數字。為了確保線程安全,使用了synchronized塊,但鎖對象的選取造成了問題。
原始代碼使用synchronized (Printer_1.class),將Printer_1類作為鎖對象。然而,代碼內部調用了實例方法wait()和notify()。 wait()和notify()方法必須作用于持有鎖的同一對象。由于使用了類鎖,而wait()和notify()操作卻在Printer_1的實例對象上進行,導致線程試圖在一個未持有的鎖上調用notify(),從而引發IllegalMonitorStateException。
立即學習“Java免費學習筆記(深入)”;
解決方法是保持鎖對象的一致性。既然使用了類鎖Printer_1.class,那么wait()和notify()也應該作用于該類鎖。正確的代碼應使用Printer_1.class.wait()和Printer_1.class.notify()替換實例方法調用。這樣,wait()和notify()操作與synchronized塊使用相同的鎖對象,避免異常。 修改后的代碼才能確保線程安全地打印數字,避免競爭條件和異常。