Java 调用中断()会中断线程,但Thread.isInterrupted()返回false
我正在使用以下测试代码测试InterruptedException:Java 调用中断()会中断线程,但Thread.isInterrupted()返回false,java,multithreading,concurrency,interrupted-exception,interruption,Java,Multithreading,Concurrency,Interrupted Exception,Interruption,我正在使用以下测试代码测试InterruptedException: Runnable runMe = new Runnable() { @Override public void run() { for(int i=0; i<6; i++) { System.out.println("i = "+i); if(i==3) { System.out.println("i==3,
Runnable runMe = new Runnable() {
@Override
public void run() {
for(int i=0; i<6; i++) {
System.out.println("i = "+i);
if(i==3) {
System.out.println("i==3, Thread = "
+Thread.currentThread().getId());
//I invoke interrupt() on the working thread.
Thread.currentThread().interrupt();
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
//I caught InterruptedException
System.out.println(Thread.currentThread().getId()
+ " is interrupted!");
Thread.currentThread().interrupt();
}
}
}
}
};
Thread workingThread = new Thread(runMe);
workingThread.start();
try {
workingThread.join();
} catch (InterruptedException e) {
//Swallow
}
//the following log shows me workingThread.isInterrupted() is false, why?
System.out.println("workingThread("
+ workingThread.getId()+") interrupted ? "
+ workingThread.isInterrupted());
Runnable runMe=new Runnable(){
@凌驾
公开募捐{
对于(int i=0;iOracle的说法(我的重点补充):
中断状态标志
中断机制使用称为中断状态的内部标志来实现。调用Thread.interrupt设置此标志。当线程通过调用静态方法Thread.interrupted检查中断时,中断状态被清除。非静态isInterrupted方法由一个线程用来查询中断状态另一方面,不改变中断状态标志
按照惯例,任何通过抛出InterruptedException退出的方法都会在抛出InterruptedException时清除中断状态
您看到的是线程被中断,退出的方法是连接(实际上连接是通过调用Object.wait实现的,所以我希望stacktrace会显示wait是引发异常的方法),并且标志被清除,如教程所述
由异常处理程序决定是否再次设置线程的中断状态标志。除非处理程序被编码为执行不同的操作,否则默认假设异常已被处理,不再需要设置标志
与此相一致的是:
如果该线程在调用对象类的wait()、wait(long)或wait(long,int)方法时被阻塞,或者在调用该类的join()、join(long)、join(long,int)、sleep(long)或sleep(long,int)方法时被阻塞,那么它的中断状态将被清除,并接收到InterruptedException
我有一个更深入的答案来解释为什么中断是这样设计的。Runnable runMe=new Runnable(){
@凌驾
公开募捐{
对于(int i=0;i<100;i++){
System.out.println(“i=“+i”);
如果(i==3){
System.out.println(“i==3,Thread=”
+Thread.currentThread().getId());
//我在工作线程上调用interrupt()。
Thread.currentThread().interrupt();
试一试{
Thread.currentThread().join();
}捕捉(中断异常e){
//我被打断了
System.out.println(Thread.currentThread().getId())
+“被打断了!”);
Thread.currentThread().interrupt();
}
}
}
}
};
Thread workingThread=新线程(runMe);
workingread.start();
睡眠(1);
//输出为true,因为子线程未失效
System.out.println(“工作读取(”
+“工作读取。getId()+”)中断?”
+工作读取。isInterrupted());
正如我在上一个问题中所指出的那样-我强烈怀疑现在死了的线程永远不会被算作被中断。@nathan Nosleep
在这里。你是在暗示他们的示例中有什么东西正在清除中断标志吗?重新打开,因为这更多的是“这里发生了什么”而不是“它为什么这样工作?”所以这两个问题看起来是不同的。