??LockSupport是一个线程工具类,所有的方法都是静态方法,可以在线程任意位置阻塞、唤醒线程。LockSupport的功能是依赖Unsafe类实现的。
??演示示例:
package com.securitit.serialize.locks;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;public class LockSupportTester {
public static void main(String[] args) throws Exception {
final Thread mainThread = Thread.currentThread();new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);System.out.println("唤醒线程:" + mainThread.getName());LockSupport.unpark(mainThread);} catch (InterruptedException ex) {
ex.printStackTrace();}}).start();System.out.println("阻塞线程:" + mainThread.getName());LockSupport.park();}}
??输出结果:
阻塞线程:main
唤醒线程:main
??从输出结果可以看出,主线程通过LockSupport.park()进行线程阻塞,新建线程通过mainThread唤醒主线程。
??源码分析:
package java.util.concurrent.locks;
import sun.misc.Unsafe;public class LockSupport {
// Construct.禁止实例化.private LockSupport() {
} // 记录线程是被blocker阻塞.private static void setBlocker(Thread t, Object blocker) {
// Even though volatile, hotspot doesn't need a write barrier here.UNSAFE.putObject(t, parkBlockerOffset, arg);}// 唤醒线程.public static void unpark(Thread thread) {
if (thread != null)UNSAFE.unpark(thread);}// 阻塞线程.public static void park(Object blocker) {
// 获取当前线程.Thread t = Thread.currentThread();// 记录线程被blocker阻塞.setBlocker(t, blocker);// 调用Unsafe.park方法阻塞线程.UNSAFE.park(false, 0L);// 清除线程被blocker阻塞的信息.setBlocker(t, null);}// 指定超时时间阻塞线程.public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
// 获取当前线程.Thread t = Thread.currentThread();// 记录线程被blocker阻塞.setBlocker(t, blocker);// 调用Unsafe.park方法阻塞线程.UNSAFE.park(false, nanos);// 清除线程被blocker阻塞的信息.setBlocker(t, null);}}// 指定阻塞线程至某个时间点.public static void parkUntil(Object blocker, long deadline) {
// 获取当前线程.Thread t = Thread.currentThread();// 记录线程被blocker阻塞.setBlocker(t, blocker);// 调用Unsafe.park方法阻塞线程.UNSAFE.park(true, deadline);// 清除线程被blocker阻塞的信息setBlocker(t, null);}// 获取线程阻塞者.public static Object getBlocker(Thread t) {
if (t == null)throw new NullPointerException();return UNSAFE.getObjectVolatile(t, parkBlockerOffset);}// 阻塞线程.public static void park() {
UNSAFE.park(false, 0L);}// 指定超时时间阻塞线程.public static void parkNanos(long nanos) {
if (nanos > 0)UNSAFE.park(false, nanos);}// 指定阻塞线程到时间点.public static void parkUntil(long deadline) {
UNSAFE.park(true, deadline);}}
??LockSupport源码实现相对比较简单,底层都是通过Unsafe的native方法由操作系统直接进行,可以提供更高的效率。
??LockSupport的park/unpark与Object的wait/notify区别:
??· wait/notify是Object的方法,在调用这两个方法前必须先获得锁,但是park不需要获取某个对象的锁就可以阻塞线程。
???· notify只能随机选择一个唤醒,无法唤醒指定线程,unpark可以唤醒一个指定的线程。
??注:文中源码均来自于JDK1.8版本,不同版本间可能存在差异。
??如果有哪里有不明白或不清楚的内容,欢迎留言哦!