对Java中interrupt、interrupted和isInterrupted的理解
对Java中interrupt、interrupted和isInterrupted的理解
一、示例
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " start...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " into catch");
System.out.println("isInterrupted: " + Thread.currentThread().isInterrupted());
}
System.out.println(Thread.currentThread().getName() + " end...");
});
t.start();
Thread.sleep(1000);
t.interrupt();
System.out.println("Main thread end...");
}
}
输出:
Thread-0 start...
Main thread end...
Thread-0 into catch
isInterrupted: false
Thread-0 end...
本示例新建了一个线程,用主线程启动,主线程睡1s,再调用子线程的interrupt()方法,子线程由于也在睡着,被打断后,输出子线程中断状态。
这里子线程的isInterrupted()方法返回是false,讲道理的话,应该返回的是true才对,因为子线程确实被中断了。Thread.sleep源码注释:
if any thread has interrupted the current thread. The <i>interrupted status</i> of the current thread is cleared when this exception is thrown.
意思是,如果任何一个线程打断了当前线程,当InterruptedException异常抛出时,那么当前线程的”中断状态“就被清除了。
二、Thread类的三个方法
2.1 interrupt
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();
}
该方法的作用是中断线程,调用该方法的线程被设置为”中断状态“。需要特别注意,调用该方法的线程只是将线程设置为中断状态,至于线程是否真的中断,要取决于线程内部的逻辑。
2.2 isInterrupted
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " start...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " into catch");
System.out.println("isInterrupted: " + Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
System.out.println("after interrupt...isInterrupted: " + Thread.currentThread().isInterrupted());
}
System.out.println(Thread.currentThread().getName() + " end...");
});
t.start();
Thread.sleep(1000);
t.interrupt();
System.out.println("Main thread end...");
}
}
输出
Thread-0 start...
Main thread end...
Thread-0 into catch
isInterrupted: false
after interrupt...isInterrupted: true
Thread-0 end...
从输出结果来看,当再次调用interrupt()方法的时候,isInterrupted的值为true,说明isInterrupt()方法不改变中断状态,只显示当前的中断状态。
2.3 interrupted
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " start...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " into catch");
System.out.println("isInterrupted: " + Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
System.out.println("after interrupt...isInterrupted: " + Thread.currentThread().isInterrupted());
Thread.interrupted();
System.out.println("after interrupted...isInterrupted: " + Thread.currentThread().isInterrupted());
}
System.out.println(Thread.currentThread().getName() + " end...");
});
t.start();
Thread.sleep(1000);
t.interrupt();
System.out.println("Main thread end...");
}
}
输出
Thread-0 start...
Main thread end...
Thread-0 into catch
isInterrupted: false
after interrupt...isInterrupted: true
after interrupted...isInterrupted: false
Thread-0 end...
可以看到,interrupted只是重置了中断状态的静态方法。