【发布时间】:2020-12-14 14:35:17
【问题描述】:
我正在阅读Java Concurrency in Practice 。在章节中的中断策略部分
取消和关闭
提到
除非任务明确设计为在具有特定中断策略的服务中运行,否则不应对其执行线程的中断策略进行任何假设。无论任务将中断解释为取消还是对中断采取其他操作,它都应该注意保留执行线程的中断状态。如果它不打算将 InterruptedException 传播给它的调用者,它应该在捕获 InterruptionException 后恢复中断状态: Thread.currentThread().interrupt()
所以我尝试使用列表示例来理解。但我对输出感到困惑。
PrimeProducer
public class CorrectPrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
public CorrectPrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" interrupt status in producer:" + Thread.currentThread().isInterrupted());
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted()) {
queue.put(p = p.nextProbablePrime());
}
} catch (InterruptedException e) {
/* Allow thread to exit */
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName()+" interrupt status in producer catch:" + Thread.currentThread().isInterrupted());
}
}
}
主要方法##
public static void main(String[] args) throws InterruptedException {
BlockingQueue<BigInteger> primes = new LinkedBlockingQueue<>();
CorrectPrimeProducer generator = new CorrectPrimeProducer(primes);
generator.start();
try {
while (needMorePrimes()) {
consume(primes.take());
}
} finally {
generator.interrupt();
}
TimeUnit.SECONDS.sleep(5);
System.out.println(generator.getName()+" interrupt status in main:"+generator.isInterrupted());
}
//do something
private static void consume(BigInteger take) {
System.out.println(take);
}
private static int counter = 1;
private static boolean needMorePrimes() {
counter++;
if(counter == 10){
// after counter reaches 10 return false
return false;
}
return true;
}
输出:
// when TimeUnit.SECONDS.sleep(5); in main class is not commented
Thread-0 interrupt status in producer:false
2
3
5
7
11
13
17
19
Thread-0 interrupt status in producer catch:true
Thread-0 interrupt status in main:false
//When TimeUnit.SECONDS.sleep(5); in main class is commented
Thread-0 interrupt status in producer:false
2
3
5
7
11
13
17
19
Thread-0 interrupt status in main:true
Thread-0 interrupt status in producer catch:true
问题
-
只需在主类的主线程中添加 TimeUnit.SECONDS.sleep(5) 即可。正在执行的线程(即生成器)中断状态正在重置。如果我评论 TimeUnit.SECONDS.sleep(5) 方法,那么在这种情况下会保留中断状态。为什么会发生这种情况以及如何发生?
-
在书中提到一个线程应该只被它的所有者打断。在上面的例子中,谁是所有者?我认为它的主要方法线程。
【问题讨论】:
-
Re,“任务不应该假设任何关于中断策略的事情......”是的,不应该。但是,如果您的代码调用任何库代码,那么您怎么知道库作者确实没有假设中断意味着整个事物正在关闭,并且他们可以放弃正在进行的工作,而
return或throw无需清理?您不知道,除非他们明确记录了他们的库如何处理中断(这几乎从来没有),或者您自己与作者交谈。我对将中断用于除关闭进程之外的任何其他目的感到非常不安。
标签: java multithreading concurrency java.util.concurrent