线程中断
中断代表线程状态,每个线程都关联了一个中断状态,是一个 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;
}
}