问题描述
有没有办法创建Executor,它总是至少有5个线程,最多20个线程,以及任务的无界队列(意味着没有任务被拒绝)
Is there any way to create Executor that will have always at least 5 threads, and maximum of 20 threads, and unbounded queue for tasks (meaning no task is rejected)
我尝试了新的 ThreadPoolExecutor(5,20,60L,TimeUnit.SECONDS,队列)
,我想到了队列的所有可能性:
I tried new ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS, queue)
with all possibilities that I thought of for queue:
new LinkedBlockingQueue() // never runs more than 5 threads
new LinkedBlockingQueue(1000000) // runs more than 5 threads, only when there is more than 1000000 tasks waiting
new ArrayBlockingQueue(1000000) // runs more than 5 threads, only when there is more than 1000000 tasks waiting
new SynchronousQueue() // no tasks can wait, after 20, they are rejected
并且没有人按原样行事。
and none worked as wanted.
推荐答案
这样的事情对你有用吗?我只是把它掀起来所以请戳它。基本上,它实现了一个溢出线程池,用于提供底层的 ThreadPoolExecutor
Maybe something like this would work for you? I just whipped it up so please poke at it. Basically, it implements an overflow thread pool that is used to feed the underlying ThreadPoolExecutor
有两个主要的缺点我看到它:
There are two major draw backs I see with it:
-
上缺少返回的Future对象submit()
。但也许这对你来说不是问题。 - 当提交作业时,辅助队列只会清空到
ThreadPoolExecutor
。必须有一个优雅的解决方案,但我还没有看到它。如果你知道在StusMagicExecutor
中会有一连串的任务,那么这可能不是问题。 (可能是关键词。)一个选项可能是让你提交的任务在完成后点击StusMagicExecutor
吗?
- The lack of a returned Future object on
submit()
. But maybe that is not an issue for you. - The secondary queue will only empty into the
ThreadPoolExecutor
when jobs are submitted. There has got to be an elegant solution, but I don't see it just yet. If you know that there will be a stead stream of tasks into theStusMagicExecutor
then this may not be an issue. ("May" being the key word.) An option might to be to have your submitted tasks poke at theStusMagicExecutor
after they complete?
Stu的魔术执行者:
Stu's Magic Executor:
public class StusMagicExecutor extends ThreadPoolExecutor {
private BlockingQueue<Runnable> secondaryQueue = new LinkedBlockingQueue<Runnable>(); //capacity is Integer.MAX_VALUE.
public StusMagicExecutor() {
super(5, 20, 60L, SECONDS, new SynchronousQueue<Runnable>(true), new RejectionHandler());
}
public void queueRejectedTask(Runnable task) {
try {
secondaryQueue.put(task);
} catch (InterruptedException e) {
// do something
}
}
public Future submit(Runnable newTask) {
//drain secondary queue as rejection handler populates it
Collection<Runnable> tasks = new ArrayList<Runnable>();
secondaryQueue.drainTo(tasks);
tasks.add(newTask);
for (Runnable task : tasks)
super.submit(task);
return null; //does not return a future!
}
}
class RejectionHandler implements RejectedExecutionHandler {
public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
((StusMagicExecutor)executor).queueRejectedTask(runnable);
}
}
这篇关于指定ThreadPoolExecutor问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!