ThreadPoolTaskExecutor遇到的坑
在利用org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
实现请求的慢处理时,我的配置中核心线程数为5,最大线程数为10,但是代码中创建了8个队列放在线程池中,假如我用id
去hash
取模,得到队列集合下标,将数据放到集合的队列中,此时就会出现8个队列中,每个队列都有数据,但只有前5个队列中的请求被处理,后3个队列的请求被搁置。
因此,配置线程池的线程最少数量时,一定要大于等于自己创建的队列数量。
出现此问题的真正原因:
如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。如果使用了无界的任务队列这个参数就没什么效果
关键配置及代码:
<bean id="deviceBindExecutor" name="deviceBindExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 线程池维护线程的最少数量 -->
<property name="corePoolSize" value="5" />
<!-- 允许的空闲时间 -->
<property name="keepAliveSeconds" value="200" />
<!-- 线程池维护线程的最大数量 -->
<property name="maxPoolSize" value="10" />
<!-- 线程池阻塞队列大小 -->
<property name="queueCapacity" value="10" />
<!-- 对拒绝task的处理策略 -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
代码实现如下:
/**
* 懒汉式单例可以实现传参的单例初始化
*/
public class RequestProcessorThreadPool {
private volatile static RequestProcessorThreadPool instance = null;
private RequestProcessorThreadPool() {
}
private RequestProcessorThreadPool(ApplicationContext applicationContext) {
RequestQueue requestQueue = RequestQueue.getInstance();
ThreadPoolTaskExecutor threadPool = (ThreadPoolTaskExecutor) applicationContext.getBean("deviceBindExecutor");
/**
* 给线程池中加入任务队列
*/
for (int i = 0; i < 8; i++) {
ArrayBlockingQueue<Request> queue = new ArrayBlockingQueue<Request>(100);
requestQueue.addQueue(queue);
threadPool.submit(new RequestProcessorThread(queue));
}
}
public static RequestProcessorThreadPool getInstance(ApplicationContext applicationContext) {
if (instance == null) {
synchronized (RequestProcessorThreadPool.class) {
if (instance == null) {
instance = new RequestProcessorThreadPool(applicationContext);
}
}
}
return instance;
}
}
还没有评论,来说两句吧...