一、线程阻塞工具类LockSupport
LockSupport
是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞。和Thread.suspend()
相比,它弥补了由于resume()
在前发生,导致线程无法继续执行的情况。和Object.wait()
相比,它不需要先获得某个对象的锁,也不会抛出InterruptedException
异常
1.1 接口描述
LockSupport
的静态方法 park()
可以阻塞当前线程,类似的还有 parkNanos()
、parkUntil()
等方
package threadPoolDemo;
import java.util.concurrent.locks.LockSupport;
public class LockSupportDemo {
public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
public static class ChangeObjectThread extends Thread {
public ChangeObjectThread(String name) {
super.setName(name);
}
public void run() {
synchronized (u) {
System.out.println("in " + getName());
LockSupport.park();
}
}
}
public static void main(String args[]) throws InterruptedException {
t1.start();
Thread.sleep(100);
t2.start();
LockSupport.unpark(t1);
LockSupport.unpark(t2);
t1.join();
t2.join();
}
}
解析
使用park()
和unpark()
方法替换掉以往的suspend()
和resume()
方法.当然我们依然无法保证unpark()
方法发生在park()方法之后,但是执行这段代码,你会发现,它自始至终都可以正常结束,不会因为park()方法而。导致线程永久性的挂起
这是因为LockSupport
类使用类似信号量的机制,他为每一个线程准备了一个许可.如果许可可用,那么park()
函数会立即返回,并消费这个许可。如果许可不可用,就会阻塞。而unpark()
则使得一个许可变为可用。
这个特点使得:即使unpark()
操作发生在park()
之前,它也可以使下一次的park()
操作立即返回.这也就是上述代码可顺利结束的主要原因.
除了有定时阻塞的功能外,LockSupport.park()
还支持中断影响,但是和其他接收中断函数不一样,LockSupport.park()不会抛出InterruptedException
异常,他只会默默的返回,但是我们可以从Thread.Interrupted()
等方法获得中断标记
package myThread;
import java.util.concurrent.locks.LockSupport;
public class LockSupportIntDemo {
public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
public static class ChangeObjectThread extends Thread {
public ChangeObjectThread(String name) {
super.setName(name);
}
public void run() {
synchronized (u) {
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 执行结束
参考
《实战java高并发程序设计》