我正在使用java.util.concurrent
的{{3}}类来创建一个固定的线程池,用于运行Web服务器的请求处理程序:
static ExecutorService newFixedThreadPool(int nThreads)
,描述是:
创建一个线程池,重用一组固定的线程,这些线程在共享的无界队列中运行。
但是,我正在寻找线程池实现,它将执行完全相同的操作,除了有界队列。有这样的实施吗?或者我是否需要为固定线程池实现自己的包装器?
答案 0 :(得分:38)
您想要做的是新建自己的ExecutorService,可能使用ThreadPoolExecutor。 ThreadPoolExecutor有一个构造函数,它接受一个BlockingQueue并获得一个有界的队列,例如ArrayBlockingQueue正确构造用于边界。您还可以包含RejectedExecutionHandler以确定队列已满时要执行的操作,或者挂起对阻塞队列的引用并使用商品提供方法。
这是一个小例子:
BlockingQueue<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<Runnable>(
100);
ExecutorService executorService = new ThreadPoolExecutor(1, 10, 30,
TimeUnit.SECONDS, linkedBlockingDeque,
new ThreadPoolExecutor.CallerRunsPolicy());
答案 1 :(得分:6)
创建一个ThreadPoolexecutor并在其中传递合适的BlockingQueue实现。例如您可以在ThreadPoolExecutor构造函数中传入ArrayBlockingQueue以获得所需的效果。
答案 2 :(得分:3)
当你创建一个ThreadPoolExecutor时,你可以给它一个有界的BlockingQueue和一个RejectedExecutionHandler,这样你就可以控制达到限制时会发生什么。默认行为是抛出RejectedExecutionException。
您还可以定义自己的线程工厂来控制线程名称并使它们成为守护程序线程。
答案 3 :(得分:3)
我用Semaphore解决了这个问题,我用它来限制提交给ExecutorService
的任务。
例如:
int threadCount = 10;
ExecutorService consumerPool = Executors.newFixedThreadPool(threadCount);
// set the permit count greater than thread count so that we
// build up a limited buffer of waiting consumers
Semaphore semaphore = new Semaphore(threadCount * 100);
for (int i = 0; i < 1000000; ++i) {
semaphore.acquire(); // this might block waiting for a permit
Runnable consumer = () -> {
try {
doSomeWork(i);
} finally {
semaphore.release(); // release a permit
}
};
consumerPool.submit(consumer);
}