Java 来自单线程执行器的RejectedExecutionException

Java 来自单线程执行器的RejectedExecutionException,java,multithreading,concurrency,runnable,executorservice,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 her

下面是我的方法,其中我有单线程执行器来执行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方法上工作,会发生什么情况?它将启动尽可能多的线程,还是等待一个线程完成,然后启动另一个线程?

请参见此处:

从错误日志中可以看到,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();
    }
}
publicstaticvoidmain(字符串[]args){
最终执行器测试et=新执行器测试();
对于(int i=0;i<50000;i++){
et.trigger(i);
}
系统输出打印项次(“完成”);
}
私有无效触发器(int i){
试一试{
Executors.newSingleThreadExecutor().execute(()->{
试一试{
睡眠(1000);
}捕获(最终中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
});
}捕获(最终异常e){
System.out.println(“用“+Thread.activeCount()”测试“+i+”);
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
  }
});
}

关于您的异常,请检查方法说明

public void execute(Runnable command)
在将来的某个时候执行给定的任务。任务可以在新线程或现有池线程中执行。如果由于此执行器已关闭或已达到其容量而无法提交任务执行,则该任务将由当前的RejectedExecutionHandler处理。


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

是的,这是完整的代码,我也提到了抛出异常的地方。您使用的是哪个版本的JDK?我使用的是JDK7。终止意味着什么?为什么会被终止?试着从文档和代码中找出服务何时会被终止。但目前我还没有答案。还尝试了一个具有长时间运行的线程和多个调用的小示例事件。我对此没有问题。你能感觉到触发器i方法被调用了多少次吗?调用是单线程的还是多线程的?我可以用50000个调用和执行时一秒钟的延迟重现您的问题-因此我猜您在使用资源时遇到了麻烦。因此ThreadPoolExecutor overrides finalize()这是一个非常糟糕的主意,尤其是在您使用它的方式中-创建许多重写finalize的对象。是的,您应该使用fixedThreadPoolSize并在外部创建执行器,因此您认为我应该创建一个大小一定的固定线程池,然后使用它,而不是每次都使用单线程执行器?是的。关机后不要向it提交任务。