關于線程暫停的方法
1.介紹
- Thread.sleep
- 線程進入 TIMED_WAITING
- 另外,該方法會拋出InterruptedException異常,這是受檢查異常,調用者必須處理。
- Object.wati()
- 該Object必須是被當前線程持有的鎖
- 線程進入WAITING狀態(tài)
- LockSupport.park()
- 底層也是調用了Unsafe類的park方法
- 調用park方法時宫屠,還允許設置一個blocker對象,主要用來給監(jiān)視工具和診斷工具確定線程受阻塞的原因
- 調用park方法進入休眠后滑蚯,線程狀態(tài)為WAITING
2. 實現原理
- LockSupport.park()
LockSupport.park() 的實現原理是通過二元信號量做的阻塞浪蹂,要注意的是,這個信號量最多只能加到1告材。我們也可以理解成獲取釋放許可證的場景坤次。unpark()方法會釋放一個許可證,park()方法則是獲取許可證斥赋,如果當前沒有許可證缰猴,則進入休眠狀態(tài),直到許可證被釋放了才被喚醒疤剑。無論執(zhí)行多少次unpark()方法洛波,也最多只會有一個許可證。
- 和wait的不同
park骚露、unpark方法和wait、notify()方法有一些相似的地方缚窿。都是休眠棘幸,然后喚醒。但是wait倦零、notify方法有一個不好的地方误续,就是我們在編程的時候必須能保證wait方法比notify方法先執(zhí)行吨悍。如果notify方法比wait方法晚執(zhí)行的話,就會導致因wait方法進入休眠的線程接收不到喚醒通知的問題蹋嵌。
而park育瓜、unpark則不會有這個問題,我們可以先調用unpark方法釋放一個許可證栽烂,這樣后面線程調用park方法時躏仇,發(fā)現已經許可證了,就可以直接獲取許可證而不用進入休眠狀態(tài)了腺办。
另外焰手,和wait方法不同,執(zhí)行park進入休眠后并不會釋放持有的鎖怀喉。
- 對中斷的處理
park方法不會拋出InterruptedException书妻,但是它也會響應中斷。當外部線程對阻塞線程調用interrupt方法時躬拢,park阻塞的線程也會立刻返回躲履。
Thread parkThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("park begin");
//等待獲取許可
LockSupport.park();
//輸出thread over.true
System.out.println("thread over." + Thread.currentThread().isInterrupted());
}
});
parkThread.start();
Thread.sleep(2000);
// 中斷線程
parkThread.interrupt();
System.out.println("main over");
# 輸出結果
park begin
main over
thread over.true
說明因park進入休眠的線程收到中斷通知后也會立刻返回,并且可以手動通過Thread.currentThread().isInterrupted()獲取到中斷位
總結
3. 關于java進程的關閉
在linux中聊闯,我們通常用kill命令來關閉一個進程工猜。眾所周知,kill有-9和-15兩種參數馅袁,默認是-15域慷。如果是-15參數,系統就發(fā)送一個關閉信號給進程汗销,然后等待進程關閉犹褒。在這個過程中,目標進程可以釋放手中的資源弛针,以及進行一些關閉操作叠骑。
正是有了這個概念,我曾經很大一段時間對java進程的關閉流程有所誤解削茁。在我原先的理解中宙枷,java進程接收到關閉信號后,會逐一給阻塞中的進程發(fā)送中斷信號茧跋,并等待線程處理完慰丛。但其實這是錯誤的。
java進程收到關閉信號后瘾杭,不會去關心運行中的那些線程是否運行完诅病,也不會給阻塞中的線程發(fā)送中斷信號。我們只能通過綁定關閉鉤子來中斷目標線程并等待線程執(zhí)行完。
java進程在收到關閉信號后贤笆,會執(zhí)行所有綁定了shutdownHook的線程蝇棉,確保這些綁定的線程都執(zhí)行完了才真正關閉。因此芥永,我們要釋放資源就要在shutdownHook的線程內操作篡殷,然后在線程內等待其他釋放資源的線程執(zhí)行完成。
注意埋涧,所有綁定了shutdownHook的線程也是并行執(zhí)行的板辽,不是順序執(zhí)行。另外飞袋,用-9參數的kill不會等shutdownHook線程執(zhí)行完就退出戳气。
參考文檔:
https://blog.csdn.net/u013332124/article/details/84647915