Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6450211

ThreadPoolExecutor.afterExecute sees RuntimeExceptions, but not Errors

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 7
    • 6
    • core-libs
    • b08
    • generic
    • generic
    • Not verified

      ThreadPoolExecutor.afterExecute takes a Throwable, and is specified to be
      passed any RuntimeException or Error thrown by the task.

      However the code only handles RuntimeException, causing the results below to
      be different for Error.

      ------------------
      import java.util.*;
      import java.util.concurrent.*;
      import java.util.concurrent.atomic.*;

      public class Bug6 {
          private static final AtomicInteger uncaughtExceptions
      = new AtomicInteger(0);

          private static final Thread.UncaughtExceptionHandler handler
      = new Thread.UncaughtExceptionHandler() {
      public void uncaughtException(Thread t, Throwable e) {
      uncaughtExceptions.getAndIncrement(); }};

          static void report(String label, ThreadPoolExecutor tpe) {
      System.out.printf("%10s: active=%d, submitted=%d, completed=%d%n",
      label,
      Thread.activeCount() - 1,
      tpe.getTaskCount(),
      tpe.getCompletedTaskCount());
          }

          static final Map<Class<?>, Integer> counts
      = new HashMap<Class<?>, Integer>();

          static class MyExecutor extends ThreadPoolExecutor {
      MyExecutor() {
      super(10, 30, 1L, TimeUnit.HOURS,
      new LinkedBlockingQueue<Runnable>());
      }

      @Override protected void afterExecute(Runnable r, Throwable t) {
      if (t != null) {
      Class<?> klazz = t.getClass();
      Integer x = counts.get(klazz);
      counts.put(klazz, x == null ? 1 : x + 1);
      }
      }
          }

          public static void main(String[] args) throws Throwable {
      Thread.setDefaultUncaughtExceptionHandler(handler);

      final int count = 8;
      final CyclicBarrier barrier = new CyclicBarrier(count + 1);
      ThreadPoolExecutor tpe = new MyExecutor();

      for (int i = 0; i < 5; i++) {
      tpe.execute(new Runnable() {
      public void run() {
      throw new RuntimeException();
      }});
      tpe.execute(new Runnable() {
      public void run() {
      throw new Error();
      }});
      }

      tpe.shutdown();
      tpe.awaitTermination(1L, TimeUnit.HOURS);

      System.out.printf("RuntimeException => %d%n",
      counts.get(RuntimeException.class));
      System.out.printf("Error => %d%n",
      counts.get(Error.class));
          }
      }
      ------------------
      $ jver 6 jr Bug6
      ==> javac -source 1.6 -Xlint:all Bug6.java
      ==> java -esa -ea Bug6
      RuntimeException => 5
      Error => null

            martin Martin Buchholz
            martin Martin Buchholz
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: