轮询空队列 - JCIP列表7.7

时间:2018-01-17 20:35:54

标签: java multithreading concurrency interrupted-exception

在此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?,但我没有足够的声誉来发表评论

2 个答案:

答案 0 :(得分:1)

中断点不是取消,当你考虑中断逻辑时,两者应该是分开的。中断可以用于取消,但如上例所示,它也可以被忽略。

可能是getNextTask(...)返回的任务非常重要,以至于线程在被中断时无法退出。因此,线程将保持阻塞,直到队列中的任务可用,除非程序完全死亡或遇到灾难性错误。

同样,这不会无限期地等待,直到有任务可用。这个示例的重要之处在于它在返回时包含一个布尔检查,它会将中断传递给调用线程。这样,当线程最终解除阻塞时,可以检查中断,以便在必要时退出。

答案 1 :(得分:0)

queue.take()会等到有东西要采取。什么都没有抛出InterruptedExcpetion所以catch块不会执行。您将保留在try块中,直到将某些内容添加到que或您抛出一个中断异常。

Thread.currentThread()。interrupt(),除非我错了,不会做太多,因为你的代码现在是单线程的,如果它在finally块中,那么单个线程已经不在try块中了。

以下是如何使用中断的示例:

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");
}


}