文章40 | 阅读 10731 | 点赞0
关于LockSupport原理看源码注释。
总的来说LockSupport提供外部使用的是静态方法park()、unpark(Thread thread)
分别是让线程阻塞和唤醒线程的两个方法
而底层则是调用C写好的库Unsafe
类实现线程的调度。这个类在juc包下的
很多类中都有用到。需要了解即可。
概括的说我们用Unsafe通过jvm操作线程,而jvm则是通过操作系统操作线程。
unpark、和park前后顺序(先阻塞,还是先唤醒)的一个坑,找到该文章的LockSupport案例
import jdk.internal.misc.Unsafe;
public class LockSupport {
private static final Unsafe U = Unsafe.getUnsafe();
private static final long PARKBLOCKER = U.objectFieldOffset(Thread.class, "parkBlocker");
private static final long TID = U.objectFieldOffset(Thread.class, "tid");
private LockSupport() {} // 构造方法私有化,不能被外部初始化
/** * @param t 需要阻塞的线程 * @param arg 引起阻塞的资源 */
private static void setBlocker(Thread t, Object arg) {
U.putReferenceOpaque(t, PARKBLOCKER, arg);
}
/** * 阻塞当前线程 */
public static void park() {
U.park(false, 0L);
}
/** * 阻塞线程 * 该方法用于系统排查和监测 */
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
U.park(false, 0L);
setBlocker(t, null);
}
/** * 解除阻塞线程 */
public static void unpark(Thread thread) {
if (thread != null)
U.unpark(thread);
}
/** * blocker是引起线程阻塞的资源 */
public static void setCurrentBlocker(Object blocker) {
U.putReferenceOpaque(Thread.currentThread(), PARKBLOCKER, blocker);
}
/** * @param blocker 阻塞的资源 * @param nanos 需要阻塞的纳秒时间 */
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
U.park(false, nanos);
setBlocker(t, null);
}
}
/** * 在指定的deadline时限前禁用当前线程,除非许可可用。 */
public static void parkUntil(long deadline) {
U.park(true, deadline);
}
/** * 带阻塞资源的,在指定的deadline时限前禁用当前线程,除非许可可用。 */
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
U.park(true, deadline);
setBlocker(t, null);
}
/** * 获取阻塞 */
public static Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
return U.getReferenceOpaque(t, PARKBLOCKER);
}
/** * 阻塞 nanos 纳秒 */
public static void parkNanos(long nanos) {
if (nanos > 0)
U.park(false, nanos);
}
/** * 获取线程的tid */
static final long getThreadId(Thread thread) {
return U.getLong(thread, TID);
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://yumbo.blog.csdn.net/article/details/109085929
内容来源于网络,如有侵权,请联系作者删除!