一、简介
LockSupport
是一个线程阻塞工具,可以在线程内任意位置让线程阻塞。
LockSupport
类使用类似信号量的机制。
-
它为每一个线程准备了一个许可,如果许可可用,那么
park()
函数会立即返回,并且消费这个许可(也就是将许可变为不可用),如果许可不可用,就会阻塞。 -
unpark()
则使得一个许可变为可用
但是与信号量不同的是:许可不能累加,你不可能拥有超过一个许可,它永远只有一个。
优点:
- 和
Thread.suspend()
相比,它弥补了由于resume()
在前发生,导致线程无法继续执行的情况 - 和
Object.wait()
相比,它不需要先获取某个对象的锁,也不会抛出InterruptedException
异常
二、LockSupport
与 线程中断
public class LockSupportIntDemo {
static ObjectThread t1 = new ObjectThread("t1");
static ObjectThread t2 = new ObjectThread("t2");
public static class ObjectThread extends Thread {
public ObjectThread(String name) {
super.setName(name);
}
@Override
public void run() {
synchronized (LockSupportIntDemo.class) {
System.out.println("in " + getName());
// 阻塞
LockSupport.park();
if (Thread.interrupted()) {
System.out.println(getName() + " 被中断");
}
}
System.out.println(getName() + "执行结束");
}
}
public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(100);
t2.start();
t1.interrupt();
LockSupport.unpark(t2);
}
}
结果如下:
in t1
t1 被中断
t1执行结束
in t2
t2执行结束
可以看出:
LockSupport.park()
支持线程中断,且改变中断表示位为 true
// t1 被操作,阻塞
LockSupport.park();
// 唤醒
t1.interrupt();
// 之后继续执行了
- 在调用完
LockSupport.park()
后,线程状态一直为 true,即使之后调用了thread.interrupt()