Object监视器和Condition的局限性
Object和Condition的等待唤醒机制有如下几点局限性:
- 线程进行等待和唤醒的先决条件是:线程获取锁
- 唤醒方法需要在等待方法之后执行才能唤醒等待方法
LockSupport类
LockSuppor工具类没有以上的缺点,可以直接阻塞线程,唤醒指定的线程,还可以提前唤醒指定线程。
LockSupport方法
- void park():阻塞当前线程,如果调用unpark方法或者当前线程被中断,从能从park()方法中返回
- void parkUntil(long deadline):阻塞当前线程,直到deadline,deadline是一个绝对时间,表示某个时间的毫秒格式
- void unpark(Thread thread):唤醒处于阻塞状态的指定线程
案例1-进行线程阻塞不需要获取锁
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
System.out.println(Thread.currentThread().getName()+"线程被park()阻塞");
LockSupport.park();
System.out.println(Thread.currentThread().getName()+"线程被唤醒");
});
t1.setName("t1");
t1.start();
TimeUnit.SECONDS.sleep(5);
LockSupport.unpark(t1);
}
}
案例2-提前执行唤醒方法
public class Demo2 {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"线程休眠5秒,等待主线程执行完");
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName()+"线程被park()方法阻塞,等待被唤醒");
LockSupport.park();
System.out.println(Thread.currentThread().getName()+"线程被唤醒,线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.setName("t1");
t1.start();
LockSupport.unpark(t1);
System.out.println("main线程执行完毕,并且提前唤醒");
}
}