轮询空队列 - JCIP 清单 7.7
Polling empty queue - JCIP listing 7.7
在这个code
public class NoncancelableTask {
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
interface Task {
}
}
如果队列已经空了怎么办?代码将首先吞下异常,然后重试 - 并永远等待?
我认为中断的主要思想是如果任务卡在 Thread.sleep、BlockingQueue.take() 等阻塞方法上时取消任务
有类似的问题 What is the point of restoring the interrupted status in JCIP listing 7.7? ,但我没有足够的声誉 post 发表评论
queue.take() 会一直等到有东西要拿。没有任何东西会抛出 InterruptedExcpetion,因此 catch 块不会执行。您将留在 try 块中,直到将某些内容添加到队列中或抛出中断异常。
Thread.currentThread().interrupt(),除非我错了,否则不会做太多,因为你的代码现在是单线程的,如果是的话,那个单线程已经在 try 块之外了在 finally 块中。
这里有一个如何使用中断的例子:
public class StoppingThreads implements Runnable
{
public static void main(String[] args)
{
Thread t0 = new Thread(new StoppingThreads());
t0.start();
Thread t1= new Thread(new StoppingThreads());
t1.start();
Thread t2 = new Thread(new StoppingThreads());
t2.start();
Thread t3 = new Thread(new StoppingThreads());
t3.start();
Thread t4 = new Thread(new StoppingThreads());
t4.start();
System.out.println("All threads started");
t0.interrupt();
t1.interrupt();
}
@Override
public void run()
{
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
System.out.println(Thread.currentThread().getName() + " Finished");
}
}
中断的重点不是取消,当你考虑中断逻辑时,两者应该分开。中断可以用于取消,但如上例一样,也可以忽略。
可能是 getNextTask(...)
返回的任务非常重要,以至于线程在中断时无法退出。因此,线程将保持阻塞状态,直到队列中有任务可用,除非程序完全死掉或遇到灾难性错误。
同样,这不是无限期地等待,直到有任务可用。这个示例之所以重要,是因为它在返回时包含一个布尔检查,这会将中断传递给调用线程。这样,当线程最终解除阻塞时,可以检查中断以在必要时退出。
在这个code
public class NoncancelableTask {
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
interface Task {
}
}
如果队列已经空了怎么办?代码将首先吞下异常,然后重试 - 并永远等待? 我认为中断的主要思想是如果任务卡在 Thread.sleep、BlockingQueue.take() 等阻塞方法上时取消任务
有类似的问题 What is the point of restoring the interrupted status in JCIP listing 7.7? ,但我没有足够的声誉 post 发表评论
queue.take() 会一直等到有东西要拿。没有任何东西会抛出 InterruptedExcpetion,因此 catch 块不会执行。您将留在 try 块中,直到将某些内容添加到队列中或抛出中断异常。
Thread.currentThread().interrupt(),除非我错了,否则不会做太多,因为你的代码现在是单线程的,如果是的话,那个单线程已经在 try 块之外了在 finally 块中。
这里有一个如何使用中断的例子:
public class StoppingThreads implements Runnable
{
public static void main(String[] args)
{
Thread t0 = new Thread(new StoppingThreads());
t0.start();
Thread t1= new Thread(new StoppingThreads());
t1.start();
Thread t2 = new Thread(new StoppingThreads());
t2.start();
Thread t3 = new Thread(new StoppingThreads());
t3.start();
Thread t4 = new Thread(new StoppingThreads());
t4.start();
System.out.println("All threads started");
t0.interrupt();
t1.interrupt();
}
@Override
public void run()
{
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
System.out.println(Thread.currentThread().getName() + " Finished");
}
}
中断的重点不是取消,当你考虑中断逻辑时,两者应该分开。中断可以用于取消,但如上例一样,也可以忽略。
可能是 getNextTask(...)
返回的任务非常重要,以至于线程在中断时无法退出。因此,线程将保持阻塞状态,直到队列中有任务可用,除非程序完全死掉或遇到灾难性错误。
同样,这不是无限期地等待,直到有任务可用。这个示例之所以重要,是因为它在返回时包含一个布尔检查,这会将中断传递给调用线程。这样,当线程最终解除阻塞时,可以检查中断以在必要时退出。