2017-11-04 285 views
0

下面是我的方法,我有单线程执行程序来执行run方法中的某个任务。RejectedExecutionException来自单线程执行程序

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 [email protected] rejected from [email protected][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方法的工作,会发生什么?它会启动多个线程,还是等待一个线程完成,然后启动另一个线程?

+0

是的,这是完整的代码,我也提到了它抛出异常的地方。 – user1950349

+0

您使用的是哪个版本的JDK? –

+0

我正在使用JDK7。 – user1950349

回答

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

终止是指什么?为什么它终止? – user1950349

+0

尝试从服务将要终止时从文档和代码中找出。但目前我没有答案。还尝试了长时间运行线程和多次调用的小样本事件。没有问题。你有没有感觉我的方法触发了多少次?这些调用是单线程还是多线程? – IEE1394

+0

我可以用50000次调用重现你的问题,执行时会延迟一秒 - 所以我想你的资源有问题 – IEE1394

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) 

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一些别的地方在你的代码。

+0

因此,你认为我应该创建一个固定的线程池,然后使用它来代替每次使用单线程执行程序? – user1950349

+0

是的。并且不要在关机后向它提交任务。 –