views:

625

answers:

5

I'm using java.util.concurrent.Semaphore in a hobby project. It's used in a connection pool class I'm writing. I can use it with little fuss, except for this method:

public void acquire(int permits) throws InterruptedException

which forces me to handle the InterruptedException. Now, I'm not sure what "interrupting" a Thread even means and I'm never doing it (well, not explicitly anyway) in my code. Does this mean I can ignore the exception? How should I handle it?

A: 

Threads can be interrupted by calling Thread.interrupt(). It is used for gracefully signalling a thread that it should do something else. Usually it causes blocking operations (e.g. Thread.sleep()) to return earlier and throw the InterruptedException. If the thread gets interrupted, a flag gets set on it. This flag can be queried via Thread.isInterrupted() call.

If you don't use thread interruption and still get this exception, you could just exit your thread (and preferrably log the exception).

In general, it depends on what your multi-threaded application does.

kd304
A: 

You should exit the run() method after you've performed any cleanup required by your Thread.
HTH

Huxi
+1  A: 

Nope. InterruptedException is only generated if you interrupt your thread yourself. If you do not yourself use Thread.interrupt() then I would either re-throw it as some sort of "unexpected exception" or log it as an error and move on. For instance in my code when I am forced to catch InterruptedException and I never call interrupt() myself, I do the equivalent of

catch (InterruptedException exception) {
    throw new RuntimeException("Unexpected interrupt", exception);
}

That's if it is unexpected. There are plenty of places where I deliberately interrupt my threads and in those cases I handle the InterruptedExceptions in a well-defined way. Usually that's by exiting whatever loop I'm in, cleaning up, and then stopping the thread.

John Kugelman
+1  A: 

If you don't know how to handle it in a method I suggest you declare it in the method with throws InterruptedException (and it caller etc)

If it something you never expect to occur I would catch it and wrap it in an AssertionError.

Peter Lawrey
+13  A: 

Yes, you need to worry about InterruptedException, just as you need to worry for any other checked exception which you must either throw or handle.

Most of the times an InterruptedException signals a stop request, most likely due to the fact that the thread which was running your code was interrupted.

In your particular situation of a connection pool awaiting to aquire a connection, I would say that this is a cancellation issue and you need to abort the aquisition, cleanup, and restore the interrupted flag (see below).


As an example, if you're using some sort of Runnable/Callable running inside an Executor then you need to handle the InterruptedException properly:

executor.execute(new Runnable() {

    public void run() {
         while (true) {
              try {
                 Thread.sleep(1000);
              } catch ( InterruptedException e) {
                  continue; //blah
              }
              pingRemoteServer();
         }
    }
});

This would mean that your task never obeys the interruption mechanism used by the executor and does not allow proper cancellation/shutdown.

Instead, the proper idiom is to restore the interrupted status and then stop execution:

executor.execute(new Runnable() {

    public void run() {
         while (true) {
              try {
                 Thread.sleep(1000);
              } catch ( InterruptedException e) {
                  Thread.currentThread().interrupt(); // restore interrupted status
                  break;
              }
              pingRemoteServer();
         }
    }
});

Useful resources:

Robert Munteanu
Absolutely. For more info, see the Java Specialists newsletter http://www.javaspecialists.co.za/archive/Issue056.html
Brian Agnew
Shouldn't it be Thread.currentThread().interrupt() rather than Thread.interrupted()? According to the javadocs, Thread.interrupted() will clear the interrupted flag, not set it.
Joe Daley
@Joe: you're right, I've correct the example. Thank you.
Robert Munteanu