Threads: Executor with launderThrowable and finally
authorGustavo Martin Morcuende <gustavo@supergusarapo.(none)>
Fri, 30 Aug 2013 21:34:28 +0000 (23:34 +0200)
committerGustavo Martin Morcuende <gustavo@supergusarapo.(none)>
Fri, 30 Aug 2013 21:34:28 +0000 (23:34 +0200)
Executor: using cancel method in a finally block should not hurt.

Allgemeines/Threads/Executor/ExecutorwithFuture/src/de/test/thread/executor/future/ThreadTest.java

index 5d7f610..7fd7060 100644 (file)
@@ -24,10 +24,15 @@ public class ThreadTest {
             } catch (final InterruptedException e) {
                 e.printStackTrace();
             } catch (final ExecutionException e) {
-                e.printStackTrace();
                 //The exception thrown in the threads is caught by the main thread here.
                 System.out.println("Exception from task " + i + ": "
                         + Thread.currentThread().getName() + "\n");
+                final Throwable cause = e.getCause();
+                // try { Uncomment this code in order to run the test. :(
+                this.launderThrowable(cause);
+                // } catch (final Throwable exception) {
+                // exception.printStackTrace();
+                // }
             } finally {
                 future[i].cancel(true);
             }
@@ -51,12 +56,38 @@ public class ThreadTest {
 
         // After exec.shutdown if we try to execute more tasks a RejectedExecutionException
         // exception will be thrown to the main thread.
-        System.out.println("Going to receive a RejectedExecutionException");
+        System.out.println("Going to receive a RejectedExecutionException ");
         for (int i = 0; i < 3; i++) {
             this.exec.execute(new ThreadExecutor(i));
         }
     }
 
+    // Before calling launderThrowable, Preloader tests for the known checked
+    // exceptions and rethrows
+    // them. That leaves only unchecked exceptions, which Preloader handles by
+    // calling launderThrowable and throwing the
+    // result. If the Throwable passed to launderThrowable is an Error,
+    // launderThrowable rethrows it directly; if it is not a
+    // RuntimeException, it throws an IllegalStateException to indicate a logic
+    // error. That leaves only RuntimeException,
+    // which launderThrowable returns to its caller, and which the caller
+    // generally rethrows
+
+    /**
+     * If the Throwable is an Error, throw it; if it is a RuntimeException
+     * return it, otherwise throw IllegalStateException
+     */
+    private RuntimeException launderThrowable(final Throwable exception) {
+        exception.printStackTrace();
+        if (exception instanceof RuntimeException)
+            return (RuntimeException) exception;
+        else if (exception instanceof Error)
+            throw (Error) exception;
+        else
+            throw new IllegalStateException("Not unchecked", exception);
+    }
+
+
     private class ThreadExecutor implements Runnable {
         int i;