使用Executors服务在Java中创建固定大小线程池的最佳方法
我正在使用Java中的使用Executors服务在Java中创建固定大小线程池的最佳方法,java,multithreading,threadpool,executorservice,Java,Multithreading,Threadpool,Executorservice,我正在使用Java中的Executors框架为多线程应用程序创建线程池,我有一个与性能相关的问题 我有一个应用程序,可以在实时或非实时模式下工作。如果是实时的,我只是使用以下方法: THREAD_POOL = Executors.newCachedThreadPool(); 但如果不是实时的,我希望能够控制线程池的大小。 要做到这一点,我考虑了两种选择,但我并不真正理解其中的区别,以及哪一种表现更好 选项1使用简单的方法: THREAD_POOL = Executors.newFixedThr
Executors
框架为多线程应用程序创建线程池,我有一个与性能相关的问题
我有一个应用程序,可以在实时或非实时模式下工作。如果是实时的,我只是使用以下方法:
THREAD_POOL = Executors.newCachedThreadPool();
但如果不是实时的,我希望能够控制线程池的大小。
要做到这一点,我考虑了两种选择,但我并不真正理解其中的区别,以及哪一种表现更好
选项1使用简单的方法:
THREAD_POOL = Executors.newFixedThreadPool(threadPoolSize);
选项2是创建我自己的ThreadPoolExecutor
,如下所示:
RejectedExecutionHandler rejectHandler = new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (Exception e) {}
}
};
THREAD_POOL = new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10000), rejectHandler);
RejectedExecutionHandler rejectHandler=新的RejectedExecutionHandler(){
@凌驾
public void rejectedExecution(可运行的r、线程池执行器执行器){
试一试{
executor.getQueue().put(r);
}捕获(例外e){}
}
};
THREAD_POOL=new ThreadPoolExecutor(threadPoolSize,threadPoolSize,0,TimeUnit.SECONDS,new LinkedBlockingQueue(10000),rejectHandler);
我想了解使用更复杂的选项2的优势是什么,以及我是否应该使用比
LinkedBlockingQueue
更复杂的数据结构?任何帮助都将不胜感激。查看源代码,您将意识到:
Executors.newFixedThreadPool(threadPoolSize);
相当于:
return new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 0L, MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
返回新的ThreadPoolExecutor(threadPoolSize,threadPoolSize,0L,毫秒,
新建LinkedBlockingQueue());
由于它不提供显式的RejectedExecutionHandler
,因此使用默认的AbortPolicy
。一旦队列已满,它基本上会抛出RejectedExecutionException
。但是队列是无限的,所以它永远不会满。因此,该执行器接受inifnite1数量的任务
您的声明要复杂得多,而且完全不同:
如果等待的任务超过10000个,则会导致线程池放弃任务newlinkedblockingqueue(10000)
- 我不明白你的
在做什么。如果池发现它不能将更多的可运行程序放入队列,它将调用您的处理程序。在这个处理器中,您。。。尝试再次将RejectedExecutionHandler
放入队列(在99%的案例块中会失败)。最后你接受了这个例外。看起来像是Runnable
ThreadPoolExecutor。丢弃策略是您所追求的 若任务队列太大,查看下面的评论似乎是在试图阻止或以某种方式限制客户端。我不认为在
内部阻塞是个好主意。取而代之的是考虑<代码> CallerRunsPolicy <代码>拒绝策略。不完全一样,但足够近RejectedExecutionHandler
1-假设2^31为无穷大则
RejectedExecutionHandler
实际上正在阻塞,调用executor.getQueue().put(r)
将一直阻塞,直到队列释放,因此最终我的处理程序允许保留一个有界队列而不中止任何任务。除非我弄错了+1了解其他细节。@charlesmengy:谢谢你的澄清,我的错,我会更新我的问题。但是,通过在RejectedExecutionHandler
内部阻塞,您希望实现什么呢?我相信它可能会有一些意想不到的副作用,比如阻塞调用线程。也许你需要callerunpolicy
?实际上看了之后,callerunpolicy
听起来对我想做的事情很有希望,我会试试的谢谢!也许你可以在答案中加上这个,我会接受你的答案。