记录一个小经验
Thread#interrupt方法到底是不是暴力停止一个线程呢?答案:否
我们用以下代码为例:
Main.java:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new MyThread();
t.start();
Thread.sleep(5);
t.interrupt();
t.join();
System.out.println("end");
}
}
MyThread.java:
public class MyThread extends Thread {
@Override
public void run() {
int n = 0;
while (true) {
n++;
System.out.println("hello " + n);
}
}
}
运行结果:
hello 1
hello 2
hello 3
...
hello 114514
...
可见线程t并没有结束。
我们观察Thread#interrupt方法本身:
// Thread.java节选
public void interrupt() {
if (this != Thread.currentThread()) {
checkAccess();
// thread may be blocked in an I/O operation
synchronized (interruptLock) {
Interruptible b = nioBlocker;
if (b != null) {
interrupted = true;
interrupt0(); // inform VM of interrupt
b.interrupt(this);
return;
}
}
}
interrupted = true;
interrupt0(); // inform VM of interrupt
}
简单来说,这个方法可以让如果状态(state)是处于BLOCKED/WAITING的线程抛出一个InterruptedException,然后将该线程的interrupted字段更改为true。
我们将MyThread.java更改为:
public class MyThread extends Thread {
@Override
public void run() {
int n = 0;
while (!isInterrupted()) {
n++;
System.out.println("hello " + n);
}
}
}
hello 1
end
程序正常运行
注:这里的hello次数和电脑算力有关,并不是必须只有一次
因此,在使用interrupt()方法时,要注意在线程内部的run()方法判断线程是否被打断,即isInterrupted()