来自单线程执行程序的RejectedExecutionException

时间:2017-11-04 01:27:31

标签: java multithreading concurrency runnable executorservice

下面是我的方法,其中我有单线程执行程序在run方法中执行某些任务。

  private void trigger(final Packet packet) {

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

以下是我得到的例外,我不确定为什么?解决这个问题的最佳方法是什么?

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)

如果我的trigger方法被多次调用并且它仍在使用我之前的线程的run方法,会发生什么?它会启动尽可能多的线程还是等待一个线程完成然后启动另一个线程?

2 个答案:

答案 0 :(得分:1)

见这里:What could be the cause of RejectedExecutionException

从错误日志中可以看出,您的ThreadPoolExecutor已终止。

也许这就是你想要的:

private void trigger(final Packet packet) {

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

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

编辑重现问题:

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();
    }
}

答案 1 :(得分:0)

在触发器方法之外创建ThreadPoolExecutor。您不应为每次通话创建newSingleThreadExecutor

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
  }
});

}

关于您的例外情况,请查看execute方法说明。

public void execute(Runnable command)
  

将来某个时间执行给定的任务。任务可以在新线程或现有池化线程中执行。如果无法提交执行任务,要么因为此执行程序已关闭,要么已达到其容量,则该任务由当前的RejectedExecutionHandler处理。

由于它是无界的队列,很可能你已经在代码中的其他地方调用了shutdown