Jdk源码分析

文章40 |   阅读 10712 |   点赞0

来源:https://yumbo.blog.csdn.net/category_10384063.html

简化 java.util.concurrent.locks.LockSupport 类的源码

x33g5p2x  于2021-12-18 转载在 其他  
字(1.9k)|赞(0)|评价(0)|浏览(248)

关于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);
    }

}

相关文章