更多 Java 并发编程方面的文章,请参见文集《Java 并发编程》
所在包 java.util.concurrent.locks
LockSupprot
是线程的阻塞原语,用来阻塞线程和唤醒线程。每个使用 LockSupport
的线程都会与一个许可 permit
关联:
- 如果该许可可用,并且可在线程中使用,则调用
park()
将会立即返回,否则可能阻塞。 - 如果许可尚不可用,则可以调用
unpark
使其可用。
注意:
- 许可不可重入,也就是说只能调用一次
park()
方法,否则会一直阻塞。 - 和信号量不同的是,这个许可不可以累加(即连续的
unpark()
和1次效果一样)。
阻塞线程
-
static void park()
:阻塞当前线程,如果调用unpark
方法或者当前线程被中断,从能从park()
方法中返回 -
static void park(Object blocker)
:功能如上,入参增加一个Object
对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查 -
static void parkNanos(long nanos)
:阻塞当前线程,最长不超过nanos
纳秒,增加了超时返回的特性 -
static void parkNanos(Object blocker, long nanos)
:功能如上,入参增加一个Object
对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查 -
static void parkUntil(long deadline)
:阻塞当前线程,直到deadline
-
static void parkUntil(Object blocker, long deadline)
:功能如上,入参增加一个Object
对象,用来记录导致线程阻塞的阻塞对象,方便进行问题排查
唤醒线程
-
static void unpark(Thread thread)
:唤醒处于阻塞状态的指定线程
实际上
LockSupport
阻塞和唤醒线程的功能是依赖于sun.misc.Unsafe
示例
public static void main(String[] args) throws Exception {
Thread t = new Thread() {
public void run() {
LockSupport.park();
System.out.println(Thread.currentThread().getName() + " started");
}
};
t.start();
Thread.sleep(2000);
LockSupport.unpark(t);
}
synchronzed VS LockSupprt
-
synchronzed
致使线程阻塞,线程会进入到 BLOCKED 状态,而调用LockSupprt.park()
方法阻塞线程会致使线程进入到 WAITING 状态 - 由
synchronzed
阻塞的线程加入到同步队列,再次被唤醒的线程是随机从同步队列中选择的,而LockSupport.unpark(thread)
可以指定线程对象唤醒指定的线程
引用:
LockSupport工具