介绍
用于创建锁和其他同步类的基本线程阻塞(不释放锁)原语。
源码
public class LockSupport {
private LockSupport() {} // 不能实例化
private static void setBlocker(Thread t, Object arg) {
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();
setBlocker(t, blocker);
UNSAFE.park(false, 0L);
setBlocker(t, null);
}
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, nanos);
setBlocker(t, null);
}
}
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(true, deadline);
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);
}
// Hotspot implementation via intrinsics API
private static final sun.misc.Unsafe UNSAFE;
private static final long parkBlockerOffset;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> tk = Thread.class;
parkBlockerOffset = UNSAFE.objectFieldOffset
(tk.getDeclaredField("parkBlocker"));
SEED = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSeed"));
PROBE = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomProbe"));
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception ex) { throw new Error(ex); }
}
}
方法 | 含义 |
---|---|
unpark(Thread thread) | 唤醒park阻塞的线程;如果没有唤醒,继续使用park将无效,不能重入 |
park(Object blocker) | jdk1.6加入,阻塞线程,可以设置阻塞对象, |
parkNanos(Object blocker, long nanos) | jdk1.6加入,阻塞线程,可以设置阻塞对象,阻塞时间(纳秒) |
parkUntil(Object blocker, long deadline) | jdk1.6加入,阻塞线程 ,可以设置阻塞对象,阻塞到某个时间点(毫秒) |
getBlocker(Thread t) | 获取线程的阻塞对象 |
park() | 阻塞对象 |
parkNanos(long nanos) | 阻塞线程,可以设置阻塞时间(纳秒 |
parkUntil(long deadline) | 阻塞线程,可以设置阻塞到某个时间点(毫秒) |
阻塞对象的添加,主要用于问题排查和系统监控;
由于在Java5之前,当线程阻塞时(使用synchronized关键字)在一个对象上时,通过线程dump能够查看到该线程的阻塞对象。方便问题定位,而Java
5退出的Lock等并发工具却遗漏了这一点,致使在线程dump时无法提供阻塞对象的信息。因此,在Java6中,LockSupport新增了含有阻塞对象的park方法。用以替代原有的park方法。
原理
看LockSupport
的源码可以看出,底部的实现依赖sun.misc.Unsafe
中的park
和unpark
方法,根据不同的操作系统做出相应的处理
public native void unpark(Object var1);
public native void park(boolean var1, long var2);