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()了当前节点;或者当前节点线程被中断返回。