线程阻塞释放的5种方法

1 LockSupport类

  • 底层使用Unsafe类
private static void block1(Thread thread) {
    new Thread(() -> {
        LockSupport.parkNanos(THREE_SECOND);
        LockSupport.unpark(thread);
    }).start();
    LockSupport.park();
}

2 Unsafe类

private static void block2(Thread thread) {
    try {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);
        new Thread(() -> {
            LockSupport.parkNanos(THREE_SECOND);
            unsafe.unpark(thread);
        }).start();
        unsafe.park(false, 0L);
    } catch (NoSuchFieldException | IllegalAccessException e) {
        e.printStackTrace();
    }
}

3 Object类

private static void block3(Thread thread) {
    new Thread(() -> {
        LockSupport.parkNanos(THREE_SECOND);
        synchronized (thread) {
            thread.notify();
        }
    }).start();

    synchronized (thread) {
        try {
            thread.wait(); // 释放锁
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

4 CountDownLatch类

private static void block4() {
    CountDownLatch latch = new CountDownLatch(1);
    new Thread(() -> {
        LockSupport.parkNanos(THREE_SECOND);
        latch.countDown();
    }).start();

    try {
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

5 自旋

private static void block5() {
    AtomicBoolean flag = new AtomicBoolean(true);
    new Thread(() -> {
        LockSupport.parkNanos(THREE_SECOND);
        flag.set(false);
    }).start();
    while (flag.get()) {
    }
}

6 测试

  • 测试误差排行(非准确测试): 自旋 < Unsafe < CountDownLatch < Object < LockSupport
public class Main {
    private static final long THREE_SECOND = 3_000_000_000L;
    private static final int times = 10;

    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis() + ":start");
        Thread thread = Thread.currentThread();
        long diff = 0;
        for (int i = 0; i < times; i++) {
            long start = System.nanoTime();
            block1(thread);//4364820
            //block2(thread);//3881931
            //block3(thread);//4358189
            //block4(); // 4309549
            //block5(); // 3473868
            diff += Math.abs(System.nanoTime() - start - THREE_SECOND);
        }
        System.out.println("block diff Time:"+diff / times);
        System.out.println(System.currentTimeMillis() + ":end");
    }
}
posted @ 2018-10-28 18:39  月下小魔王  阅读(3291)  评论(0编辑  收藏  举报