他们是LockSupport中的方法
//暂停当前线程
LockSupport.park();
//恢复某个线程的运行,参数需要传递要恢复的线程是哪个
LockSupport.unPark(Thread thread);
注意:unpark既可以在park之前调用,也可以在park之后调用;也就是说park先暂停了某个线程,可以通过unPark恢复,也可以在park暂停之前就先恢复某个线程;
正常情况下暂停一秒线程,两秒后恢复线程:
//正常情况
public static void main(String[] args) {
try {
Thread thread = new Thread(() -> {
log.debug("start...");
try {
TimeUnit.SECONDS.sleep(1);
log.debug("park...");
LockSupport.park();
log.debug("已经唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
thread.start();
//两秒后唤醒
TimeUnit.SECONDS.sleep(2);
log.debug("--unpark");
LockSupport.unpark(thread);
} catch (Exception e) {
e.printStackTrace();
}
}
-----输出
[t1] DEBUG com.example.myproject - start...
[t1] DEBUG com.example.myproject - park...
[main] DEBUG com.example.myproject --unpark
[t1] DEBUG com.example.myproject- 已经唤醒
非正常情况暂停两秒线程,却在1秒的时候就恢复,也就是unpark在park之前调用
//正常情况
public static void main(String[] args) {
try {
Thread thread = new Thread(() -> {
log.debug("start...");
try {
//这里改为暂停2秒
TimeUnit.SECONDS.sleep(2);
log.debug("park...");
LockSupport.park();
log.debug("已经唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
thread.start();
//这里改为1秒后唤醒
TimeUnit.SECONDS.sleep(1);
log.debug("--unpark");
LockSupport.unpark(thread);
} catch (Exception e) {
e.printStackTrace();
}
}
-----输出,这里的结果就是先唤醒,然后在执行的park
[t1] DEBUG com.example.myproject - start...
[main] DEBUG com.example.myproject --unpark
[t1] DEBUG com.example.myproject - park...
[t1] DEBUG com.example.myproject- 已经唤醒
与Object方法中的wait¬ify区别
- park & unprk是LockSupport的方法,而wait、notify是Object的方法;
- wait、notify和notifyAll必须配合synchronize一起使用,而park,unpark不需要;
- park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,因为unpark需要传递一个线程参数,所以unpark能【精确】的唤醒线程;而notify只能随机唤醒一个等待的线程,notifyAll是唤醒所有等待线程,就不是那么【精确】。
- park & unprk 可以先unpark,在park,没有顺序,而wait & notify则必须先wait,才能notify,必须有顺序。