park和unpark方法詳解


簡述

  他們都是LockSupport,park用於暫停某個線程,unpark用於恢復某個線程的運行。

@slf4j
public class Test {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            log.debug("start...");
            sleep(1);
            log.debug("park...");
            LockSupport.park();
            log.debug("resume...");
        }, "t1");
        t1.start();
        sleep(2);
        log.debug("unpark...");
        LockSupport.unpark(t1);
    }
}

  輸出

18:43:50.765 c.TestParkUnpark [t1] - start... 
18:43:51.764 c.TestParkUnpark [main] - unpark... 
18:43:52.769 c.TestParkUnpark [t1] - park... 
18:43:52.769 c.TestParkUnpark [t1] - resume...

特點

  park和unpark一起使用時,可以先unpark,后park的線程停止后會自動喚醒

@slf4j
public class Test {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            log.debug("start...");
            sleep(2);
            log.debug("park...");
            LockSupport.park();
            log.debug("resume...");
        }, "t1");
        t1.start();
        sleep(1);
        log.debug("unpark...");
        LockSupport.unpark(t1);
    }
}

  輸出

18:43:50.765 c.TestParkUnpark [t1] - start... 
18:43:51.764 c.TestParkUnpark [main] - unpark... 
18:43:52.769 c.TestParkUnpark [t1] - park... 
18:43:52.769 c.TestParkUnpark [t1] - resume...

與Object的wait&notify對比

  wait,notify 和 notifyAll 必須配合 Object Monitor 一起使用,而 park,unpark 不必

  park & unpark 是以線程為單位來【阻塞】和【喚醒】線程,而 notify 只能隨機喚醒一個等待線程,notifyAll是喚醒所有等待線程,就不那么【精確】

  park & unpark 可以先 unpark,而 wait & notify 不能先 notify

park&unpark原理

  park和unpark會調用Unsafe類中的native方法

  每個線程都會和一個park對象關聯起來,由三部分組成 _counter , _cond 和 _mutex。核心部分是counter,我們可以理解為一個標記位。

  當調用park時會看counter是否為0,為0則進入阻塞隊列。為1則繼續運行並將counter置為0。

  當調用unpark時,會將counter置為1,若之前的counter值為0,還喚醒阻塞的線程。

 

  

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM