簡述
他們都是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¬ify對比
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,還喚醒阻塞的線程。