我想创建一个ThreadPoolExecutor,这样当它达到最大大小并且队列已满时,submit()方法会在尝试添加新任务时阻塞。我是否需要为此实现一个自定义的RejectedExecutionHandler,或者是否有一种现有的方法可以使用标准的Java库来实现此目的?
发布于 2010-01-05 02:20:29
我刚刚找到的一个可能的解决方案是:
public class BoundedExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command)
throws InterruptedException, RejectedExecutionException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
}还有其他的解决方案吗?我更喜欢基于RejectedExecutionHandler的东西,因为它似乎是处理这种情况的标准方法。
发布于 2011-04-14 06:15:09
您可以使用ThreadPoolExecutor和blockingQueue:
public class ImageManager {
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(blockQueueSize);
RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.CallerRunsPolicy();
private ExecutorService executorService = new ThreadPoolExecutor(numOfThread, numOfThread,
0L, TimeUnit.MILLISECONDS, blockingQueue, rejectedExecutionHandler);
private int downloadThumbnail(String fileListPath){
executorService.submit(new yourRunnable());
}
}发布于 2010-01-05 02:07:23
您应该使用CallerRunsPolicy,它在调用线程中执行被拒绝的任务。这样,在任务完成之前,它不能向executor提交任何新任务,此时将有一些空闲的池线程,否则进程将重复。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.CallerRunsPolicy.html
从文档中:
拒绝的任务
在方法执行(java.lang.Runnable)中提交的新任务将在Executor关闭时被拒绝,当Executor对最大线程和工作队列容量使用有限的界限时也是如此,并且是饱和的。在这两种情况下,execute方法都会调用其RejectedExecutionHandler的RejectedExecutionHandler.rejectedExecution(java.lang.Runnable,java.util.concurrent.ThreadPoolExecutor方法。提供了四个预定义的处理程序策略:
。
此外,在调用ThreadPoolExecutor构造函数时,请确保使用有界队列,如ArrayBlockingQueue。否则,什么都不会被拒绝。
编辑:响应您的评论,将ArrayBlockingQueue的大小设置为等于线程池的最大大小,并使用AbortPolicy。
编辑2:好的,我明白你的意思了。这样如何:重写beforeExecute()方法以检查getActiveCount()是否超过getMaximumPoolSize(),如果超过了,则休眠并重试?
https://stackoverflow.com/questions/2001086
复制相似问题