gpt4 book ai didi

java - Java线程InterruptExceptioon处理仅在某些情况下阻止了进一步的代码执行

转载 作者:行者123 更新时间:2023-12-03 13:23:00 25 4
gpt4 key购买 nike

以下简短的示例代码说明了我无法解释的行为

    ConcurrentLinkedDeque<Double> testQueue = new ConcurrentLinkedDeque<>();

Thread t = new Thread(() -> {
long cnt = 0;
try {
while(!Thread.currentThread().isInterrupted()) {
testQueue.add(Math.random());
cnt++;
try {
Thread.sleep(100);
}catch (Exception e) {
System.out.println(String.format("inner interrupted inserted %d record", cnt));
}
}
} catch (Exception e) {
System.out.println(String.format("interrupted inserted %d record", cnt));
}
System.out.println(String.format("inserted %d record", cnt));
});
如果我调用 t.interrupt()来中断线程
预期的行为是2条显示以下内容的行:
inner interrupted inserted %d record
inserted %d record
其中%d被替换为相应的值。
但实际结果是
inner interrupted inserted %d record
如果我们将内部捕获移除到线程
    ConcurrentLinkedDeque<Double> testQueue = new ConcurrentLinkedDeque<>();

Thread t = new Thread(() -> {
long cnt = 0;
try {
while(!Thread.currentThread().isInterrupted()) {
testQueue.add(Math.random());
cnt++;
Thread.sleep(100);
}
} catch (Exception e) {
System.out.println(String.format("interrupted inserted %d record", cnt));
}
System.out.println(String.format("inserted %d record", cnt));
});
然后我们得到输出
interrupted inserted %d record
inserted %d record
正如预期的那样,现在外部捕获正在捕获InterruptException
但是,如果我改为在第一个代码示例的最内层捕获中放置中断,如下所示:
    ConcurrentLinkedDeque<Double> testQueue = new ConcurrentLinkedDeque<>();

Thread t = new Thread(() -> {
long cnt = 0;
try {
while(!Thread.currentThread().isInterrupted()) {
testQueue.add(Math.random());
cnt++;
try {
Thread.sleep(100);
}catch (Exception e) {
System.out.println(String.format("inner interrupted inserted %d record", cnt));
break; //this one
}
}
} catch (Exception e) {
System.out.println(String.format("interrupted inserted %d record", cnt));
}
System.out.println(String.format("inserted %d record", cnt));
});
产生了预期的行为。
挡块的位置为什么会产生这种差异?

最佳答案

请参阅 Thread#interrupt 的文档:

If this thread is blocked in an invocation of [...] sleep(long), or sleep(long, int), [...], then its interrupt status will be cleared and it will receive an InterruptedException.


If none of the previous conditions hold then this thread's interrupt status will be set.


这意味着在您的示例中, Thread#sleep均会抛出异常XOR Thread.currentThread().isInterrupted()给您true。
因此,在第一个示例中,您捕获到异常,执行打印并在无限循环中输入/停留,因为 Thread.currentThread().isInterrupted()始终为 false
在您的第二个示例中,try-catch没有嵌套在循环内,因此两次打印均会发生,并且线程将按预期终止。
在第三个示例中,您只是明确退出了循环。

仅供引用:您无需编写 System.out.println(String.format(...))。有 System.out.printf,但请不要忘记 \n

关于java - Java线程InterruptExceptioon处理仅在某些情况下阻止了进一步的代码执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64921763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com