有没有什么方法可以创建至少有 5 个线程、最多 20 个线程和无限任务队列的执行器(意味着没有任务被拒绝)
我尝试了新的 ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS, 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
没有一个能如愿以偿。
最佳答案
也许这样的事情对你有用?我刚把它搅起来,所以请戳一下。基本上,它实现了一个溢出线程池,用于提供底层 ThreadPoolExecutor
我看到它有两个主要缺点:
submit()
上缺少返回的 Future 对象。但也许这对您来说不是问题。- 辅助队列只会在提交作业时清空到
ThreadPoolExecutor
。必须有一个优雅的解决方案,但我还没有看到它。如果您知道StusMagicExecutor
中会有稳定的任务流,那么这可能不是问题。 (“可能”是关键词。)一个选项可能是让您提交的任务在完成后戳StusMagicExecutor
?
斯图的魔法执行者:
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);
}
}
关于java - 指定 ThreadPoolExecutor 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1435903/