How can I make ThreadPoolExecutor command wait if there's too much data it needs to work on?
Instead of an open-ended queue, you can use a BlockingQueue
with a limit on it:
BlockingQueue<Date> queue = new ArrayBlockingQueue<Date>(200);
In terms of jobs submitted to an ExecutorService
, instead of using the default ExecutorService
s created using Executors
, which use an unbounded queue, you can create your own:
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(200));
Once the queue fills up, it will cause it to reject any new tasks that are submitted. You will need to set a RejectedExecutionHandler
that submits to the queue. Something like:
final BlockingQueue queue = new ArrayBlockingQueue<Runnable>(200);
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS, queue);
// by default (unfortunately) the ThreadPoolExecutor will throw an exception
// when you submit the 201st job, to have it block you do:
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// this will block if the queue is full
executor.getQueue().put(r);
}
});
I think it's a major miss that Java doesn't have a ThreadPoolExecutor.CallerBlocksPolicy
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…