下面是我的方法,其中我有单线程执行器来执行运行方法中的某些任务。
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();
}
}
在触发器方法之外创建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)
在将来的某个时候执行给定的任务。任务可以在新线程或现有池线程中执行。如果无法提交任务执行,无论是因为此执行程序已关闭还是已达到其容量,则该任务将由当前拒绝执行处理程序处理。
由于它是无限队列,因此很可能您在代码中的其他位置调用了shutdown
。