线程中断
中断代表线程状态,每个线程都关联了一个中断状态,是一个 true 或 false 的 boolean 值,初始值为 false。
Thread类中的有个三个关于中断的方法
public void interrupt(){}
中断目标线程,线程中断状态true。 ```java public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {                                      
    Interruptible b = blocker;                                    
    if (b != null) {                                              
        interrupt0();           // Just to set the interrupt flag 
        b.interrupt(this);                                        
        return;                                                   
    }                                                             
}                                                                 
interrupt0();                                                     
}
- 当线程被Object中定义的 wait()、wait(long)或wait(long, int)以及Thread中的jion()、join(long)、join(long, int)、sleep(long)或sleep(long, int)进入阻塞状态,调用interrupt()时线程的中断标记会被清除(设置为false),同时抛出一个InterruptedException异常。
- 当线程处于非阻塞的运行状态时,调用interrupt()方法不会响应。一般通过Thread.isInterrupted()判断状态。
##### public static boolean interrupted() {} 
```java
public static boolean interrupted() {                                      
    return currentThread().isInterrupted(true);                            
}
用于判断当前线程的中断状态,调用时会清除当前线程的中断状态(置为flase),连续调用两次返回false。
public boolean isInterrupted() {}
public boolean isInterrupted() {                                           
    return isInterrupted(false);                                           
}
判断目标线程是否被中断,不会清除中断标记。
中断状态被清除的特殊情况
1.当一个线程处于被阻塞状态,使用public void interrupt(){}方式中断该线程,将会抛出一个InterruptedException的异常,同时中断状态将会被清除(从true变成false)
 public static void main(String[] args) {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                // while在try中,通过异常中断就可以退出run循环
                try {
                    while (true) {
                        // 当前线程处于阻塞状态,异常必须捕捉处理,无法往外抛出
                        Thread.sleep(2000);
                    }
                } catch (InterruptedException e) {
                    System.out.println("Interruted When Sleep");
                    boolean interrupt = this.isInterrupted();
                    // 中断状态被复位
                    System.out.println("interrupt:" + interrupt);
                }
            }
        };
        t1.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 中断处于阻塞状态的线程
        t1.interrupt();
    }
输出
Interruted When Sleep
interrupt:false
要注意while中判断的写法,容易引起死循环。
while(!this.isInterrupted())
中断与synchronized
线程的中断操作对于正在等待获取的锁对象的synchronized方法或者代码块并不起作用
public class ThreadInterruptTest {
    public static void main(String[] args) {
        try {
            Object object = new Object();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        synchronized (object) {
                            Thread.sleep(5000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            Thread.sleep(2000);
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (object){
                        System.out.println("get lock");
                    }
                }
            });
            thread.start();
            Thread.sleep(1000);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
5秒之后打印:
get lock
如何退出线程?
1.使用voliate变量
public class Interrupt {
    private volatile static boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (!flag) {
                System.out.println("thread Running");
            }
            System.out.println("thread break");
        });
        thread.start();
        Thread.sleep(2000);
        flag = true;
    }
}