park() 阻塞一个线程
- 在线程内调用 LockSupport.park() 会暂停当前线程;若是在 park() 之前就调用了 LockSupport.unpark(threadName) ,那么线程在遇到 park() 时,将不会被阻塞。如:
public static void main(String[] args) {
Thread newThread = new Thread(() -> {
LockSupport.unpark(Thread.currentThread()); // 提前为当前线程服用解药
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
LockSupport.park(); // 当前不会中毒阻塞在这里
System.out.println("no park....");
});
newThread.start();
}
输出结果:
unpark(thread) 唤醒一个线程
- unpark(thread) 一般用于精准地唤醒指定的线程,以达到准确控制线程的执行顺序。如
public static void main(String[] args) {
Thread newThread = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("park....");
LockSupport.park(); // 阻塞当前线程
System.out.println("unpark.....");
});
newThread.start();
try {
Thread.sleep(3000);
System.out.println("main unpark newThread");
LockSupport.unpark(newThread); // 为指定的线程解除阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
}
执行结果如下:
park()/unpark() 与 wait/notify/notifyAll 进行对比
- park 能让当前线程进入阻塞状态,wait 也可以让当前线程进入阻塞状态;
- park 不会释放锁资源,而 wait 会释放锁资源;
- park 可以先调用 unpark 避免自身进入阻塞状态,而 wait 不能先调用 notify/notifyAll 避免自身进入阻塞状态;
- unpark 能准确地让指定的线程从阻塞状态中醒过来,而 notify 只能从等待的线程中随机唤醒一个。