线程阻塞工具:LockSupport

LockSupport是一个实用的线程阻塞工具,提供了线程阻塞和唤醒的静态方法。

LockSupport使用类似信号量的机制。当调用LockSupport.unpark()时,给当前线程提供了一个调用LockSupport.park()的许可。和信号量不同的是,这个许可不可以累加(即连续的unpark()和1次效果一样)。提供的主要方法如下:

// 阻塞当前线程,只有调用unpark(Thread thread)或者当前线程被中断,才能返回
public static void park();
// 在park()方法的基础上增加了超时时间,单位为nanos纳秒
public static void parkNanos(long nanos);
// 唤醒处于阻塞状态的thread
public static void unpark(Thread thread);
// 阻塞当前线程,知道deadline(从1970年到现在的毫秒数)
public static void parkUntil(long deadline);

下面给出一个简单的demo:

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);
		}

		@Override
		public void run() {
			synchronized (u) {
				System.out.println("in " + getName());
				LockSupport.park();
				System.out.println("===========");
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		t1.start();
		Thread.sleep(100);
		t2.start();
		LockSupport.unpark(t1);
        // LockSupport.unpark(t1);
		Thread.sleep(2000);
		LockSupport.unpark(t2);
		t1.join();
		t2.join();
	}

}

从上述代码可以看出,LockSupport.unpark(t1)执行的条件是,有在线程t1里面执行LockSupport.park(),否则会阻塞。如果在主线程里执行两次LockSupport.unpark(t1),则效果还是一样的。