我試圖更多地了解 Thread.interrupt(),因此我撰寫了以下代碼。
public class Test {
private Object object = new Object();
Runnable thread1 = () -> {
synchronized (object) {
System.out.println(System.currentTimeMillis() " - Thread1 inside synchronized block");
try {
object.wait();
System.out.println(System.currentTimeMillis() " - Thread1 after wait()");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() " - Thread1 ending");
}
};
Runnable thread2 = () -> {
synchronized (object) {
System.out.println(System.currentTimeMillis() " - Thread2 inside synchronized block");
try {
Thread.sleep(2000);
System.out.println(System.currentTimeMillis() " - Thread2 after sleep");
object.notify();
System.out.println(System.currentTimeMillis() " - Thread2 after notify()");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() " - Thread2 ending");
}
};
public void run() {
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
t1.interrupt();
}
public static void main(String[] args) {
new Test().run();
}
}
我無法理解結果。首先,為什么輸出的第三行沒有顯示例外堆疊跟蹤?第一個執行緒在第二個執行緒仍在休眠時被中斷,因此例外應該在第二個執行緒醒來之前發生。其次,為什么“執行緒 1 結束”出現在堆疊跟蹤之前?
1643099950931 - Thread1 inside synchronized block
1643099950947 - Thread2 inside synchronized block
1643099952947 - Thread2 after sleep
1643099952947 - Thread2 after notify()
1643099952947 - Thread2 ending
1643099952947 - Thread1 ending
java.lang.InterruptedException
at java.base/java.lang.Object.wait(Native Method)
at java.base/java.lang.Object.wait(Object.java:328)
at com.ocbc.ms.Test.lambda$new$0(Test.java:13)
at java.base/java.lang.Thread.run(Thread.java:834)
uj5u.com熱心網友回復:
從Thread.wait(以粗體突出顯示的相關部分)的檔案中:
使當前執行緒等待直到它被喚醒,通常是通過通知或中斷,或者直到經過一定的實時時間。
...
此方法使當前執行緒(此處稱為 T)將自己置于此物件的等待集中,然后放棄對該物件的任何和所有同步宣告。
然后執行緒T出于執行緒調度目的而被禁用并處于休眠狀態,直到發生以下情況之一:
...
其他一些執行緒中斷執行緒 T。
...
然后將執行緒T從該物件的等待集中移除,并重新啟用執行緒調度。它以通常的方式與其他執行緒競爭物件同步的權利;一旦它重新獲得了對物件的控制權,它對物件的所有同步宣告都將恢復到之前的狀態——即,恢復到呼叫等待方法時的狀態。執行緒 T 然后從呼叫等待方法回傳。因此,從等待方法回傳時,物件和執行緒 T 的同步狀態與呼叫等待方法時完全相同。
也就是說,當執行緒 1 被主執行緒中斷時,它仍然要等待執行緒 2 完成釋放它的鎖,然后執行緒 1 才會重新獲得對鎖的控制權并繼續。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/422756.html
標籤:
