Java Interrupts

As of Ice 3.6, Java applications can safely interrupt a thread that calls a blocking Ice API.

You must enable the Ice.ThreadInterruptSafe property to use interrupts. Enabling interrupts causes Ice to disable message buffer caching, which may incur a slight performance penalty.

With interrupt support enabled, Ice guarantees that every call into the run time that could potentially block indefinitely is an interruption point. On entry, an interruption point raises the unchecked exception Ice.OperationInterruptedException immediately if the current thread's interrupted flag is true. If the application interrupts the run time after the interruption point has begun its processing, the interruption point will either raise Ice.OperationInterruptedException or return control to the application with the thread's interrupted flag set. Under no circumstances will Ice silently discard an interrupt.

For example, the following code shows how to interrupt a thread that's blocked while making a synchronous proxy invocation:

Java
Thread proxyThread = Thread.currentThread();
AccountPrx account = // get proxy...
 
try {
    String name = account.getName(); // Blocks calling thread
    ...
} catch (Ice.OperationInterruptedException ex) {
   // The invocation was interrupted.
}
 
// At this point either the invocation was interrupted with an
// OperationInterruptedException or proxyThread.isInterrupted() is true.
 
// In another thread either just prior to or during the getName() invocation.
proxyThread.interrupt();

Here is a similar example that uses the asynchronous proxy API instead:

Java
Thread proxyThread = Thread.currentThread();
AccountPrx account = // get proxy...

Ice.AsyncResult r = account.begin_getName(); // Never blocks

try {
    // do more work
    String name = account.end_getName(r); // May block calling thread
    ...
} catch (Ice.OperationInterruptedException ex) {
    // The invocation was interrupted.
}
 
// At this point either the invocation was interrupted with an
// OperationInterruptedException or proxyThread.isInterrupted() is true.
 
// In another thread either just prior to or during the getName() invocation.
proxyThread.interrupt();

Synchronous proxy invocations are interruption points. For an asynchronous proxy invocation, the begin_ method never blocks and therefore it is not an interruption point, however the end_ method is an interruption point.

Additionally, all of the methods listed in Blocking API Calls are also interruption points. In the specific case of Communicator.destroy(), we recommend calling destroy in a loop as shown below:

Java
while(true) {
  try {
    communicator.destroy();
    break;
  } catch(Ice.OperationInterruptedException ex) {
    continue;
  }
}

Interrupting a call to destroy could leave the Ice run time in a partially-destroyed state; calling destroy again as we've done here ensures Ice can finish reclaiming the communicator's resources.

See Also