Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: rearranged CSs

...

The task does not notify upper layers when it terminates unexpectedly as a result of the runtime exception. Moreover, it does not use any recovery mechanism.

Compliant Solution (

...

This compliant solution uses a Future object to catch any exception thrown by the task. It uses the ExecutorService.submit() method to submit the task so that a Future object can be obtained.

Code Block
bgColor#ccccff

final class PoolService {
  private final ExecutorService pool = Executors.newFixedThreadPool(10);

  public void doSomething() {     
    Future<?> future = pool.submit(new Task());

    // ... 

    try {
      future.get();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt(); // Reset interrupted status      
    } catch (ExecutionException e) {
      Throwable exception = e.getCause();      
      // Forward to exception reporter
    }
  }  
}

Any exception that precludes doSomething() from obtaining the Future value can be handled as required.

Compliant Solution (ThreadPoolExecutor hooks)

Wiki Markup
Task specific recovery or clean-up actions can also be performed by overriding the class {{java.util.concurrent.ThreadPoolExecutor}}'s {{afterExecute()}} hook. This hook is called when a task completes successfully by executing all statements in its {{run()}} method, or halts because of an exception (A {{java.lang.Error}} might not be captured on specific implementations, see [Bug ID 6450211|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6450211] \[[SDN 08|AA. Java References#SDN 08]\]). When using this approach, substitute the executor service with a custom {{ThreadPoolExecutor}} that overrides the {{afterExecute()}} hook as shown below:

...

Wiki Markup
Note that the uncaught exception handler is not called if the method {{ExecutorService.submit()}} is invoked. This is because the thrown exception is considered to be part of the return status and is consequently, re-thrown by {{Future.get()}}, wrapped in an {{ExecutionException}} \[[Goetz 06|AA. Java References#Goetz 06]\]. 

Compliant Solution (Future<V> and submit())

This compliant solution uses a Future object to catch any exception thrown by the task. It uses the ExecutorService.submit() method to submit the task so that a Future object can be obtained.

Code Block
bgColor#ccccff

final class PoolService {
  private final ExecutorService pool = Executors.newFixedThreadPool(10);

  public void doSomething() {     
    Future<?> future = pool.submit(new Task());

    // ... 

    try {
      future.get();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt(); // Reset interrupted status      
    } catch (ExecutionException e) {
      Throwable exception = e.getCause();      
      // Forward to exception reporter
    }
  }  
}

Any exception that precludes doSomething() from obtaining the Future value can be handled as required.

Exceptions

EX1: This guideline may be violated if the code for all runnable and callable tasks has been audited to ensure that no exceptional conditions are possible.

...