LockSupport注意事项


前言

原本以为LockSupport的park()方法会直接阻塞线程, 但是在阅读AQS源码的时候, 发现不是这个样子, 所以这里也记录一下LockSupport的park()方法的一些注意事项

LockSupport.park()

  1. 功能: 阻塞当前线程
  2. park方法只要线程设置了中断标志位,就直接返回,且不会清除中断标志位.
  3. 如下两个条件任何一个成立,park()都不会阻塞:
    1. 中断标志位存在(wait,join,sleep或Thread.interrupted()都会清除中断标志位)
    2. _counter为1(之前调用了unpark或者interrupt)
  4. sleep方法响应中断, 会修改标志位, 但是不会修改_counter
  5. 执行Thread.interrupted()会复位, 并且清空_counter

LockSupport.park() 不阻塞的场景

线程被设置了中断标志位的情况下, park()方法不会阻塞

@Test
public void lockSupport3() throws InterruptedException {
    LOGGER.info("start");
    Thread thread = new Thread(() -> {
        LOGGER.info("thread start");
        long start = System.currentTimeMillis();
        while ((System.currentTimeMillis() - start) < 3L) {
        }
        LockSupport.park();
        LOGGER.info("thread end");
    });
    thread.start();
    // 中断线程
    thread.interrupt();
    Thread.sleep(5L);
    LOGGER.info("end");
}

通过响应sleep()中断异常, 清除了中断标志位

响应sleep()方法的中断不会更改_counter, 所以park()还是不会阻塞线程

/**
 * 响应sleep()方法导致中断标志被清除, 但是LockSupport.park()方法还是不会阻塞
 */
@Test
public void lockSupport() throws InterruptedException {
    final String mark = "interrupt state:{}";
    Thread thread = new Thread(() -> {
        LOGGER.info("i`m start");
        LOGGER.info(mark, Thread.currentThread().isInterrupted());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // sleep()方法响应中断会清除标志位, 但是不会更改_counter
            LOGGER.info(mark, Thread.currentThread().isInterrupted());
        }
        LOGGER.info("i`m work");
        LockSupport.park();
        LOGGER.info(mark, Thread.currentThread().isInterrupted());
        LOGGER.info("i`m end");
    }, "lockSupport");
    thread.start();
    thread.interrupt();
    Thread.sleep(1000);
    LOGGER.info("thread end");
}

在unpark()方法之前执行了park()方法

/**
 * 在park之前执行unpark()方法, 线程不会阻塞
 */
@Test
public void lockSupport2() {
    LOGGER.info("start");
    LockSupport.unpark(Thread.currentThread());
    /*不会阻塞*/
    LockSupport.park();
    LOGGER.info("end");
}
posted @ 2020-12-09 19:35  梅子酒zZ  阅读(78)  评论(0编辑  收藏  举报