[英]OCJP Dumps Thread Synchronized Method
嗨,我正在處理SCJP轉儲,但現在遇到了問題。 這是問題:
void waitForSignal(){
Object obj = new Object();
synchronized(Thread.currentThread()){
obj.wait();
obj.notify();
}
}
哪個論述是對的?
答:此代碼可以引發InterruptedException
B.這段代碼會拋出一個非法的MonitorStateException
C.此代碼可以在十分鍾后引發TimeoutException
D.顛倒obj.wait()和obj.notify()的順序可能會導致此方法正常完成
E.從另一個線程調用notify()或notifyAll()可能導致此方法正常完成
F.除非將“ obj.wait()”替換為“((Thread)obj).wait()”,否則不會編譯此代碼。
我發現在一個轉儲文件中答案是A,而在另一個轉儲文件中答案是B。任何人都可以找到正確的答案並為我提供解釋嗎?
絕對B在這里是正確的。 請參閱IllegalMonitorStateException的API文檔:
拋出該異常指示線程試圖在對象的監視器上等待,或者通知其他線程在對象監視器上等待而沒有擁有指定的監視器。
所獲取的監視器是當前線程(順便說一下,API文檔警告不要這樣做)。 在obj上調用了wait和notify方法,該方法應該在當前線程對象上調用。
答:Object#wait可以引發InterruptedException。 語言規范說:是否會發生這種情況取決於實現方式:
令線程t為在對象m上執行wait方法的線程,令n為t對m進行的,未與解鎖動作匹配的鎖定動作的數量。 發生以下操作之一:
如果n為零(即線程t尚未擁有對目標m的鎖定),則將引發IllegalMonitorStateException。
如果這是定時等待,並且nanosecs參數不在0-999999范圍內,或者millisecs參數為負,則拋出IllegalArgumentException。
如果線程t被中斷,則拋出InterruptedException,並且t的中斷狀態設置為false。
否則,將發生以下順序:(...)
因此,沒有嚴格定義將首先檢查哪些情況。 實際上,在Oracle或IBM JDK中不會拋出InterruptedException,而在IllegalMonitorStateException中會拋出InterruptedException。
但是此代碼本身不會導致InterruptedException,因此需要在線程上調用中斷。 我用來嘗試的代碼是:
public class Test implements Runnable {
public void run() {
Object obj = new Object();
Thread.currentThread().interrupt();
try {
synchronized(Thread.currentThread()) {
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Thread(new Test()).start();
}
}
因此,A在理論上可能是正確的。 認證測試問題必須合理明確,規范在這一點上有點模棱兩可,這使我認為這不是一個很好的測試問題。
C.“ TimeoutException”是偽造的。 如果等待超時超時,則該方法正常返回。
D.反轉等待和通知呼叫的順序無關緊要,它們都有相同的要求。
E.另一個線程所做的任何事情都不能使該線程在編寫時正常完成。
F.方法等待在對象而不是線程上,不需要強制轉換。
鑒於B絕對是正確的,並且它描述了Java程序員需要理解的重要點,而A基於對規范的模糊理解,如果您只能選擇一個答案,我建議B。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.