具有有界队列的Java线程池
我正在使用具有有界队列的Java线程池,java,multithreading,threadpool,Java,Multithreading,Threadpool,我正在使用java.util.concurrent的类创建一个固定线程池,用于运行web服务器的请求处理程序: static ExecutorService newFixedThreadPool(int nThreads) 描述如下: 创建一个线程池,该线程池重用一组固定的线程,这些线程在共享的无界队列中运行 然而,我正在寻找线程池实现,它将做完全相同的事情,除了使用有界的队列。是否有这样的实施?或者我需要为固定线程池实现自己的包装器吗?在其中创建并传递合适的BlockingQueue实现
java.util.concurrent
的类创建一个固定线程池,用于运行web服务器的请求处理程序:
static ExecutorService newFixedThreadPool(int nThreads)
描述如下:
创建一个线程池,该线程池重用一组固定的线程,这些线程在共享的无界队列中运行
然而,我正在寻找线程池实现,它将做完全相同的事情,除了使用有界的队列。是否有这样的实施?或者我需要为固定线程池实现自己的包装器吗?在其中创建并传递合适的BlockingQueue实现。例如,您可以在ThreadPoolExecutor构造函数中传入一个,以获得所需的效果。创建ThreadPoolExecutor时,您可以给它一个bounded BlockingQueue和RejectedExecutionHandler,以便控制达到限制时发生的情况。默认行为是抛出RejectedExecutionException
您还可以定义自己的线程工厂来控制线程名称并使它们成为守护进程线程。您要做的是创建自己的ExecutorService,可能使用。ThreadPoolExecutor有一个构造函数,它接受BlockingQueue并获取一个绑定队列,例如,您可以使用它来正确构造绑定队列。您还可以包括,以便确定队列已满时要做什么,或者挂起对阻塞队列的引用并使用offer方法 下面是一个小示例:
BlockingQueue<Runnable> linkedBlockingDeque = new LinkedBlockingDeque<Runnable>(
100);
ExecutorService executorService = new ThreadPoolExecutor(1, 10, 30,
TimeUnit.SECONDS, linkedBlockingDeque,
new ThreadPoolExecutor.CallerRunsPolicy());
BlockingQueue linkedBlockingDeque=新建linkedBlockingDeque(
100);
ExecutorService ExecutorService=新线程池Executor(1,10,30,
TimeUnit.SECONDS,linkedBlockingDeque,
新的ThreadPoolExecutor.CallerRunPolicy());
我用一个用于限制提交给执行器服务的任务的方法解决了这个问题
例如:
int threadCount=10;
ExecutorService consumerPool=Executors.newFixedThreadPool(线程计数);
//将许可计数设置为大于线程计数,以便
//建立一个有限的等待消费者缓冲区
信号量信号量=新信号量(threadCount*100);
对于(int i=0;i<1000000;++i){
semaphore.acquire();//这可能会阻止等待许可证
可运行消费者=()->{
试一试{
doSomeWork(i);
}最后{
semaphore.release();//释放许可证
}
};
consumerPool.submit(消费者);
}
你知道为什么没有“PostingBlocksPolicy”阻止任务发布吗?我想确保这项工作(最终)完成,因此放弃或中止策略都不起作用,CallerRuns也不起作用,因为我使用(单线程)线程池的全部目标是确保在特定的单线程上完成工作。实际上没有,这可能被称为“笨拙”如果要实现一个,因为调用方永远无法控制等待。但是,您可以直接调用linkedBlockingDequeue.offer(x)并对结果执行一些操作。while(!linkedBlockingDequa.offer(myRunnable)){//wait,或采取一些措施,或抛出异常}如果池中有两个阻塞挂起的任务和两个线程,如果将队列大小设置为5,并再添加一个任务,则该任务将需要很长时间才能执行,或者如果有两个线程挂起,则可能never@AlexPunen对然后呢?有很多方法可以管理这种情况,但这超出了问题的范围。如果您自己在发布问题后遇到此问题,我相信您也会提供:p此解决方案可能导致许可泄漏。例如,如果future在有效执行之前被取消,信号量将永远不会被释放,一个许可证将永远丢失。如果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);
}