一、打断正常运行的线程,不会清空打断状态

打断正常运行的线程, 不会清空打断状态

  1. private static void test2() throws InterruptedException {
  2. Thread t2 = new Thread(()->{
  3. while(true) {
  4. Thread current = Thread.currentThread();
  5. boolean interrupted = current.isInterrupted();
  6. if(interrupted) {
  7. log.debug(" 打断状态: {}", interrupted); //true
  8. break;
  9. }
  10. }
  11. }, "t2");
  12. t2.start();
  13. sleep(0.5);
  14. t2.interrupt();
  15. }

二、打断park的线程,不会清空打断状态

private static void test3() throws InterruptedException {
        Thread t1 = new Thread(() -> {
                log.debug("park...");
                LockSupport.park();
                log.debug("unpark...");
                log.debug("打断状态:{}", Thread.currentThread().isInterrupted()); //true
         }, "t1");
        t1.start();
        sleep(0.5);
        t1.interrupt();
}

输出
21:11:52.795 [t1] c.TestInterrupt - park... 
21:11:53.295 [t1] c.TestInterrupt - unpark... 
21:11:53.295 [t1] c.TestInterrupt - 打断状态:true

如果打断标记已经是 true, 则 park 会失效! 可以调用Thread.interrupted()清除打断标记

private static void test4() {
        Thread t1 = new Thread(() -> {
        for (int i = 0; i < 5; i++) {
                log.debug("park...");
                LockSupport.park();
                log.debug("打断状态:{}", Thread.currentThread().isInterrupted());
         }
         });
    t1.start();
    sleep(1);
    t1.interrupt();
}

输出
21:13:48.783 [Thread-0] c.TestInterrupt - park... 
21:13:49.809 [Thread-0] c.TestInterrupt - 打断状态:true 
21:13:49.812 [Thread-0] c.TestInterrupt - park... 
21:13:49.813 [Thread-0] c.TestInterrupt - 打断状态:true 
21:13:49.813 [Thread-0] c.TestInterrupt - park... 
21:13:49.813 [Thread-0] c.TestInterrupt - 打断状态:true 
21:13:49.813 [Thread-0] c.TestInterrupt - park... 
21:13:49.813 [Thread-0] c.TestInterrupt - 打断状态:true 
21:13:49.813 [Thread-0] c.TestInterrupt - park... 
21:13:49.813 [Thread-0] c.TestInterrupt - 打断状态:true

Thread.currentThread().isInterrupted() 判断当前线程是否被打断,不会清除打断标记

**

Thread.interrupted() 判断当前线程是否被打断,会清除打断标记

三、打断 sleep wait join 的线程,会清空打断状态

:::tips sleep wait join 的线程如果被打断,会直接清除打断标记,将打断标记设置为false :::

打断wait

public class WaitNotifyInterupt {
    static Object obj = new Object();
    public static void main(String[] args) {
        Thread threadA = new Thread(() -> {
            synchronized (obj) {
                try {
                    System.out.println("begin");
                    obj.wait();
                    System.out.println("end");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        threadA.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadA.interrupt();
        System.out.println("Thread end");
    }


}

为什么sleep的线程被打断之后会清除打断标记?

正常线程调用interrupt()不能被打断 给你一个打断标记你自己根据标记去判断
如果是sleep,则会响应打断所以会清除打断标记;

打断sleep

import java.util.concurrent.TimeUnit;

class Lock3 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("t1------");
            try {
                TimeUnit.SECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");
        t1.start();

        //主要为了让子线程 t1先运行
        TimeUnit.SECONDS.sleep(1);
        //本来你这里做了对t1的打断操作 为什么sleep要清除
        t1.interrupt();
        //false
        System.out.println("t1的打断标记" + t1.isInterrupted());  //false
    }