LockSupport简介
LockSupport用来实现线程的挂起和唤醒,它是Java6引入的一个工具类,它简单灵活,应用广泛,同时也是构建同步组件的基础工具。
LockSupport API
// 阻塞当前线程,调用unpark(Thread thread)方法或者当前线程被中断,才能从park返回
void park()
// 阻塞当前线程但时间不超过nanos纳秒
void parkNanos(long nanos)
// 阻塞当前线程直到deadline时间(从1970开始到deadline时间毫秒数)
void parkUntil(long deadline)
// 唤醒处于阻塞状态的线程
void unpark(Thread thread)
// java6增加了以下3个方法
void park(Object blocker)
void parkNanos(Object blocker,long nanos)
void parkUntil(Object blocker,long deadline)
用于实现阻塞当前线程的功能,blocker用于标识当前线程正在等待的对象(阻塞对象),该对象主要用于给开发人员提供阻塞对象的信息,有助于问题排查和系统监控。
Object等待唤醒wait/notify/notifyAll
// object wait notify
public static void main(String[] args) throws InterruptedException {
final Object obj = new Object();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
synchronized (obj){
obj.wait();
}
}catch (Exception e){
e.printStackTrace();
}
System.out.println("go here");
}
});
thread.start();
Thread.sleep(1000);
synchronized (obj){
obj.notify();
}
}
// 上述睡眠一秒钟,保证线程thread阻塞在wait方法,若此处注释,主线程先notify,
// 可能程序一直处于wait等待状态,所以必须先阻塞后notify。
// 可见Object的wait与notify的调用是有先后顺序的。
LockSupport阻塞唤醒park/unpark
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
LockSupport.park();
}catch (Exception e){
e.printStackTrace();
}
System.out.println("go here");
}
});
thread.start();
LockSupport.unpark(thread);
}
// LockSupport支持主线程先调用unpark后,线程thread再调用park而不被阻塞。
总结一下,LockSupport与Object(wait/notify)不同点:
-
①LockSupport不需要在同步代码块里 ,所以线程间也不需要维护一个共享的同步对象,实现了线程间的解耦。
-
②unpark函数可以先于park调用,所以不需要担心线程间的执行的先后顺序。
-
③多次调用unpark方法和调用一次unpark方法效果一样,比如线程A连续调用两次LockSupport.unpark(B)方法唤醒线程B,然后线程B调用两次LockSupport.park()方法, 线程B依旧会被阻塞。因为两次unpark调用效果跟一次调用一样,只能让线程B的第一次调用park方法不被阻塞,第二次调用依旧会阻塞。
原文链接:https://blog.csdn.net/jiangtianjiao/article/details/86693898
网友评论