来自单线程执行器的 RejectedExecutionException

RejectedExecutionException coming from single thread executor

下面是我的方法,其中我有单线程执行器在 运行 方法中执行一些任务。

  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@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 方法被多次调用并且它仍在处理我之前线程中的 运行 方法,会发生什么情况?它会启动尽可能多的线程还是等待一个线程完成然后启动另一个线程?

看这里: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();
    }
}

在触发方法之外创建 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)

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.

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