
前言
在前面的文章中,我們介紹了并發(fā)工具中的4個,Samephore,CyclicBarrier,CountDownLatch,Exchanger,但是我們漏了一個,非常的好用的工具,樓主在這里必須加上。
LockSupport
LockSupport 是一個非常方便實用的線程阻塞工具,他可以在任意位置讓線程阻塞。并且是靜態(tài)的方法。是不是很心動?
LockSupport 的靜態(tài)方法 park()可以阻塞當(dāng)前線程,類似的還有 parkNanos(),parkUntil()等,他們實現(xiàn)了一個限時的等待。
同樣的,有阻塞的方法,當(dāng)然有喚醒的方法,什么呢?unpark(Thread) 方法。該方法可以將指定線程喚醒。
我們還是來一個例子吧,看看到底有多好用:
public class LockSupportInterruptDemo {
static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
static class ChangeObjectThread extends Thread {
public ChangeObjectThread(String name) {
super.setName(name);
}
public void run() {
synchronized (u) {
System.out.println("in " + getName());
// wait
LockSupport.park();
if (Thread.interrupted()) {
System.err.println(getName() + "被中斷了");
}
}
System.out.println(getName() + "執(zhí)行結(jié)束了");
}
}
public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(3000);
t1.interrupt();
// notify
LockSupport.unpark(t2);
}
}
執(zhí)行結(jié)果:

完全實現(xiàn)了 wait notify 的功能,但是,請注意,park 方法和 wait 方法相比,不需要獲取某個對象的鎖,也不會拋出 InterruptedException 異常,因此,你需要像我們的例子一樣,使用靜態(tài)方法進(jìn)行判斷。
如果你將 park 方法改成 park(this)/park(Thread),那么在打印 線程dump 信息的時候會打印阻塞對象的詳細(xì)信息。

該方法和 Lock 接口一樣都是使用的 sun.misc.Unsafe 的 park 方法實現(xiàn)的阻塞。
還有一個需要注意的是:park 方法和 unpark 方法執(zhí)行順序不是那么的嚴(yán)格。比如我們在 Thread 類中提到的 suspend 方法 和resume 方法,如果順序錯誤,將導(dǎo)致永遠(yuǎn)無法喚醒,但 park 方法和 unpark 方法則不會,我們測試一下,將 unpark 方法緊跟著 start 方法后面執(zhí)行,那么也就是說,unpark 方法在 線程2 的park 方法之前執(zhí)行,但結(jié)果相同。

我們將 unpark 方法移動到了 start 方法后面,依然正確執(zhí)行。
什么原因呢?這是因為 LockSupport 使用了類似信號量的機(jī)制。他為每一個線程準(zhǔn)備了一個許可(默認(rèn)不可用),如果許可能用,那么 park 函數(shù)會立即返回,并且消費(fèi)這個許可(也就是將許可變?yōu)椴豢捎?/strong>),如果許可不可用,將會阻塞。而 unpark 方法則使得一個許可變?yōu)榭捎?/strong>(但是和信號量不同的是,許可不能累加,你不可能擁有超過要給許可,他永遠(yuǎn)只有一個)。
下面是JDK文檔:


這個特定使得:即使 unpark 方法在 park 方法之前執(zhí)行,他也可以使下一次的 park 操作立即返回。這也使上面的代碼能正確執(zhí)行的原因。
好了,到這里,LockSupport 就介紹完了,可以說,該方法可以替代 wait ,notify ,Condition 的 await ,signal 方法。注意,這里的 park 方法底層和 Lock 的底層實現(xiàn)是一致的。都是掉喲個 sun.misc.Unsafe。這個類可以說很牛逼。
good luck ?。。?!