RejectedExecutionException coming from single thread executor

Viewed 6737

Below is my method in which I have single thread executor to execute some task in the run method.

  private void trigger(final Packet packet) {

    // this line is throwing exception
    Executors.newSingleThreadExecutor().execute(new Runnable() {
      @Override
      public void run() {
        // some code here
      }
    });
  }

Below is the exception I am getting and I am not sure why? What is the best way to fix this?

error= java.util.concurrent.RejectedExecutionException: Task com.abc.stuffProc$2@e033da0 rejected from java.util.concurrent.ThreadPoolExecutor@76c2da8f[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
    at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:628)

What happens if my trigger method is called many times and it is still working on the run method from my previous threads? Will it launch as many threads or it will wait for one thread to finish and then start another thread?

2 Answers

See here: What could be the cause of RejectedExecutionException

as you could see from the error log, your ThreadPoolExecutor is Terminated.

Maybe this is what you want:

private void trigger(final Packet packet) {

    executor.execute(new Runnable() {
      @Override
      public void run() {
        // some code here
      }
    });
  }

private final ExecutorService executor = Executors.newFixedThreadPool(10);

EDIT Reproduce the Problem with:

public static void main(String[] args) {
    final ExecutorTest et = new ExecutorTest();
    for (int i = 0; i < 50000; i++) {
        et.trigger(i);
    }
    System.out.println("Done");
}

private void trigger(int i) {

    try {
        Executors.newSingleThreadExecutor().execute(() -> {
            try {
                Thread.sleep(1000);
            } catch (final InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });
    } catch (final Exception e) {
        System.out.println("Test " + i + " with " + Thread.activeCount());
        e.printStackTrace();
    }
}

Create ThreadPoolExecutor outside of your trigger method. You should not create newSingleThreadExecutor for every call.

private ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private void trigger(final Packet packet) {

executorService .execute(new Runnable() {
  @Override
  public void run() {
    // some code here
  }
});

}

Regarding your exception, please check execute method description.

public void execute(Runnable command)

Executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread. If the task cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been reached, the task is handled by the current RejectedExecutionHandler.

Since it's unbounded queue, most likely you have called shutdown some where else in your code.

Related