java帐篷_Java多线程之 Park和Unpark(十四)
介紹
Park 和 Unpark 均是 LockSupport 類中的方法
//暫停當前線程
LockSupport.park();
//恢復某個線程
LockSupport.unpark(暫停線程對象);
先 park 再unpark
Thread thread = new Thread(() -> {
System.out.println("start.....");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("park....");
LockSupport.park();
System.out.println("resume.....");
});
thread.start();
Thread.sleep(2000);
System.out.println("unpark....");
LockSupport.unpark(thread);
運行結果
Connected to the target VM, address: '127.0.0.1:2352', transport: 'socket'
start.....
park....
unpark....
resume.....
注意:
park 中的線程,處于 WAIT 狀態
unpark 既可以在 park 之前調用或之后調用,都是用來恢復某個線程的運行,簡單的說,調用 unpark 后再調用 park 線程依然不會暫停,類似提前“解毒”。
特點
與 Object 的 wait & notify 相比
wait,notify 和 notifyAll 必須配合 Object Monitor 一起使用,而 unpark 不必
park & unpark 是以線程為單位來【阻塞】和【喚醒】線程,而 notify 只能隨機喚醒一個等待線程,notifyAll 是喚醒所以等待線程,就不那么【精確】
park & unpark 可以先 unpark ,而 wait & notify 不能先 notify
原理
每個線程都有自己的一個 Parker 對象(C 實現的),由三部分組成 _counter, _cond, 和 _mutex
舉個例子,把線程比喻成一個旅行者, Parker 就是他背著的旅行包,條件變量(_cond) 好比背包中帳篷。_counter 好比背包中的備用干糧( 0 為耗盡, 1 為充足)
調用 park 就是看線程需不需要停下來休息
若備用干糧耗盡( _counter 為 0) ,則鉆進帳篷休息(線程暫停)
若備用干糧充足(_counter 為 1),則不需要停留繼續前進 (線程繼續運行)
調用 unpark ,相當于補充干糧(把 _counter 設置為 1)
如果此時線程 還在帳篷(先調用 park) ,則喚醒他繼續前進(線程繼續運行)
如果線程還在運行,下次調用 park 時,僅是消耗備用干糧(把 _counter 設置為 0) ,不需要停留繼續前進。
如果此時線程還在運行,那么下次他(線程)調用park時,僅是消耗備用干糧,不需要停留繼續前進
因為背包空間有限,多次調用 unpark 僅會補充一份備用干糧
詳細
1)調用 park
當前線程調用 park() 方法
檢查_counter,本情況為 0 此時獲得 _mutex 互斥鎖
線程進入 _cond 條件變量阻塞
設置 _counter = 0
2)調用 unpark
調用 unpark(Thread_0)方法,設置 _counter 為 1
喚醒 _cond 條件變量中的 Thread_0 (線程)
Thread_0 恢復運行
設置 _counter 為 0
3)先調用 unpark 再調用 park
調用 unpark (Thread_0) 方法,設置_counter 為 1
當前線程調用 park() 方法
檢查 _counter ,本情況為 1 ,這時線程無需阻塞,繼續運行
設置 _counter 為 0
總結
以上是生活随笔為你收集整理的java帐篷_Java多线程之 Park和Unpark(十四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交换机是如何对数据包打标签去标签的_条形
- 下一篇: oracle back log,11g闪