在Java中使用RejectedExecutionException
时处理ThreadPoolExecutor
的最佳方法是什么?
我想确保提交的任务不应该被忽视,并且肯定会被执行。截至目前,完成任务还没有硬实时要求。
我认为可以完成的其中一件事就是在循环中等待,直到我知道可运行队列中有空间,然后继续将其添加到队列中。
如果人们可以分享他们的经历,我们会很高兴。
通过以下方式添加可能的解决方案:
while(executor.getQueue().remainingCapacity <= 0){
// keep looping
Thread.sleep(100);
};
//if the loop exits ,indicates that we have space in the queue hence
//go ahead and add to the queue
executor.execute(new ThreadInstance(params));
答案 0 :(得分:3)
我会改变队列的行为。 e.g。
public class MyBlockingQueue<E> extends ArrayBlockingQueue<E> {
private final long timeoutMS;
public MyBlockingQueue(int capacity, long timeoutMS) {
super(capacity);
this.timeoutMS = timeoutMS;
}
@Override
public boolean offer(E e) {
try {
return super.offer(e, timeoutMS, TimeUnit.MILLISECONDS);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
return false;
}
}
}
这会在放弃之前等待队列消耗。
答案 1 :(得分:2)
如果你已经约束你的线程池只允许一定数量的并发线程(通常是好事),那么应用程序需要以某种方式推回调用代码,所以当你从ThreadPoolExecutor收到RejectedExecutionException时你我需要向来电者表明这一点,来电需要处理重试。
类似情况是负载较重的Web服务器。客户端连接,Web服务器应返回503 - 服务不可用(通常是临时条件),客户端决定如何处理它。