Thread的Interrupt操作


前言

Java提供了好几种与interrupt有关的方法, 比较容易弄混, 在此总结一下, 形成文字

线程实例方法 interrupt()

为线程设置中断标志, 但是线程需要主动响应InterruptedException异常, 获取轮训interrupt状态来响应外部的中断

private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final String THREAD_NAME = "interrupted-thread";

@Test
public void testInterrupt1() throws InterruptedException {
    Thread thread = new Thread(() -> {
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            // 通过InterruptedException异常响应中断
            // 这里的state会输出为false,因为thread响应之后会将标志位清零
            LOGGER.info("i was interrupted, current state {}", Thread.currentThread().isInterrupted());
        }
    }, THREAD_NAME);
    thread.start();
    Thread.sleep(1000L);
    // 中断线程
    thread.interrupt();
    Thread.sleep(3000L);
}

/**
 * 线程不会收到任何干扰
 */
@Test
public void testInterrupt2() throws InterruptedException {
    Thread thread = new Thread(() -> {
        long start = System.currentTimeMillis();
        while ((System.currentTimeMillis() - start) < 10L) {
            LOGGER.info("I`m busy");
        }
        // state true 状态发生改变 但是线程并不会因此终止
        LOGGER.info("My State is {}", Thread.currentThread().isInterrupted());
    }, THREAD_NAME);
    thread.start();
    Thread.sleep(5L);
    // 中断
    thread.interrupt();
    Thread.sleep(10L);
}

线程实例方法 isInterrupted()

一般通过Thread.currentThread()来调用, Thread.currentThread().isInterrupted(), 用于获取当前线程的中断状态, 且不会清除这个状态

@Test
public void testInterrupt4() throws InterruptedException {
    Thread thread = new Thread(() -> {
        long start = System.currentTimeMillis();
        while ((System.currentTimeMillis() - start) < 10L) {
            // 获取标识位,并且不修改标识位
            if (Thread.currentThread().isInterrupted()) {
                LOGGER.info("somebody has interrupt me, ignore it...");
            } else {
                LOGGER.info("I`m busy...");
            }
        }
        LOGGER.info("I`m done with my job");
    }, THREAD_NAME);
    thread.start();
    Thread.sleep(5L);
    // 中断
    thread.interrupt();
    Thread.sleep(10L);
}

线程静态方法 Thread.interrupted()

Thread类的静态方法, 用于获取当前的标志位状态, 并且将其复位, 也就是设置为false

@Test
public void testInterrupt3() throws InterruptedException {
    Thread thread = new Thread(() -> {
        long start = System.currentTimeMillis();
        boolean interrupt = false;
        while ((System.currentTimeMillis() - start) < 10L) {
            // Thread.interrupted()获取标识位,清除标志位状态
            boolean interrupted = Thread.interrupted();
            if (interrupted) {
                LOGGER.info("线程中断,但是不响应这个中断,当前标志位:{}", Thread.currentThread().isInterrupted());
                interrupt = true;
            } else if (interrupt) {
                LOGGER.info("线程被中断一次, 但是线程并未停止");
                break;
            } else {
                LOGGER.info("I`m busy...");
            }
        }
        LOGGER.info("I`m done with my job");
    }, THREAD_NAME);
    thread.start();
    Thread.sleep(5L);
    // 中断
    thread.interrupt();
    Thread.sleep(10L);
}
posted @ 2020-12-09 19:15  梅子酒zZ  阅读(135)  评论(0编辑  收藏  举报