1

In this 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 {
    }
}

What if queue is already empty? Code will swallow first exception, then retry - and wait forever? I thought main idea of interruption is cancellation of task if it stuck on some blocking method like Thread.sleep, BlockingQueue.take(), etc.

There is similar question What is the point of restoring the interrupted status in JCIP listing 7.7? , but I don't have enough reputation to post a comment

Pasharik
  • 61
  • 5

2 Answers2

1

The point of interruption is not cancellation, the two should be separate when you are thinking about interruption logic. Interruption can be used for cancellation, but as in the sample above, it can also be ignored as well.

It could be that the task returned by getNextTask(...) is so important that the thread cannot afford to exit when interrupted. Therefore, the thread will remain blocked until a task is available in the queue, unless the program completely dies or encounters a catastrophic error.

Again, this is not waiting indefinitely, only until there is a task available. What makes this sample important is that it contains a boolean check when returning, which will pass the interruption to the calling thread. That way, when the thread finally unblocks, an interruption can be checked for it to exit if necessary.

0

queue.take() will wait until there is something to take. Nothing is throwing an InterruptedExcpetion so the catch block won't execute. You will remain in the try block until something is added to the que or you throw an interupted exception.

Thread.currentThread().interrupt(), unless I am wrong, will not do much, because your code is single threaded right now, and that single thread is already out of the try block if it is in the finally block.

Here is an example of how to use interrupt:

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


}