park / unpark
用法
// 暂停当前线程
LockSupport.park();
// 恢复某个线程的运行
LockSupport.unpark(暂停线程对象)
**先说结论:**无论unpark在park前还是后,都可以解除暂停状态。
先park在unpark可以成功运行:
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);
先unpark再park也可以成功运行:
Thread t1 = new Thread(() -> {log.debug("start...");try {sleep(2);} catch (InterruptedException e) {e.printStackTrace();}log.debug("park...");LockSupport.park();log.debug("resume...");},"t1");t1.start();sleep(1);log.debug("unpark...");LockSupport.unpark(t1);
与wait/notify区别
特点 与 Object 的 wait & notify 相比
- wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用(也就是先获取对象的锁),而 park,unpark 不必。
- park & unpark 是以线程为单位来【阻塞】和【唤醒(指定)】线程,而 notify 只能随机唤醒一个等待线程,notifyAll是唤醒所有等待线程,就不那么【精确】。
- park & unpark 可以先 unpark,而 wait & notify 不能先 notify。
如果先unpark,在park之前,counter会先+1,把unpark存储,等park的时候再使用。当然只能存储一次。