LockSupport類在jdk源碼中基本定義就是創建鎖和其他同步類的 基本線程阻塞原語,直接與UnSafe
類打交道,Unsafe類中眾多的native方法實現都是基于C++語言的,而且與系統平臺相關,這里基本不做闡述。這里主要說明LockSupport的使用方式。
常見使用方式
LockSupport.park()
LockSupport.unpark(Thread t)
park()方法會阻塞當前線程(線程進入Waiting狀態),除非它獲取了"許可證"。
unpark(Thread t)方法會給線程t頒發一個"許可證"。
從park()方法的官方注釋中,我們發現還有其他的方式可以使park()方法返回。
/**
* Disables the current thread for thread scheduling purposes unless the
* permit is available.
*
* <p>If the permit is available then it is consumed and the call
* returns immediately; otherwise the current thread becomes disabled
* for thread scheduling purposes and lies dormant until one of three
* things happens:
*
* <ul>
*
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
*
* <li>Some other thread {@linkplain Thread#interrupt interrupts}
* the current thread; or
*
* <li>The call spuriously (that is, for no reason) returns.
* </ul>
*
* <p>This method does <em>not</em> report which of these caused the
* method to return. Callers should re-check the conditions which caused
* the thread to park in the first place. Callers may also determine,
* for example, the interrupt status of the thread upon return.
*/
public static void park() {
UNSAFE.park(false, 0L);
}
三種原因中的第二種是其他線程中斷線程t時,線程t會從park()方法返回。測試代碼如下:
public class LockSupportUse {
public static void main(String[] args) {
testParkThenInterrupt();
}
public static void testParkThenInterrupt(){
Thread thread = new Thread(new LockSupportThread(), "LockSupportThread");
thread.start();
SleepUtil.sleep(2);
//充分運行線程LockSupportThread兩秒鐘后,中斷該線程,
//該線程能從park()方法返回
thread.interrupt();
//LockSupport.unpark(thread);
}
static class LockSupportThread implements Runnable{
@Override
public void run() {
LockSupport.park(); //阻塞自己
System.out.println(Thread.currentThread().getName() + "從park()中返回");
}
}
}
它的應用在同步器AbstractQueueSynchronizer
中有所體現,一個節點線程獲取不到鎖時,會阻塞自己,調用的就是LockSupport的park()方法,返回只有兩種方式,前一個節點線程釋放鎖時unpark()了當前節點;或者當前節點線程被中斷返回。