<bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="6"/>
<property name="maxPoolSize" value="6"/>
<property name="queueCapacity" value="5"/>
<property name="keepAliveSeconds" value="120"/>
<property name="threadNamePrefix" value="myThread_"/>
</bean>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) context.getBean("threadPoolTaskExecutor");
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<1000;i++){
list.add(i);
if(6 == list.size()){
doWork(list,executor);
list.clear();
}
}
if(list.size() > 0)
doWork(list,executor);
System.out.println("all work finished");
}
static void doWork(List<Integer> list,ThreadPoolTaskExecutor executor){
final CountDownLatch latch = new CountDownLatch(list.size());
for(final int i:list){
executor.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(200);
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
以上是我的代码。当我设置queueCapacity 6或大于6时,它运行良好,但当queueCapacity小于6时程序将出错:
> Exception in thread "main"
> org.springframework.core.task.TaskRejectedException: Executor
> [java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size =
> 6, active threads = 0, queued tasks = 5, completed tasks = 18]] did
> not accept task: com.my.service.test.Test$1@1de8526; nested exception
> is java.util.concurrent.RejectedExecutionException: Task
> com.my.service.test.Test$1@1de8526 rejected from
> java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size =
> 6, active threads = 0, queued tasks = 5, completed tasks = 18] at
> org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:305)
> at com.my.service.test.Test.doWork(Test.java:42) at
> com.my.service.test.Test.main(Test.java:27) at
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:606) at
> com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
> Caused by: java.util.concurrent.RejectedExecutionException: Task
> com.my.service.test.Test$1@1de8526 rejected from
> java.util.concurrent.ThreadPoolExecutor@1f7911b[Running, pool size =
> 6, active threads = 0, queued tasks = 5, completed tasks = 18] at
> java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
> at
> java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
> at
> java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
> at
> org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:302)
> ... 7 more
谁能告诉我为什么?当一个任务放到rarad池时,poll firt把任务放到了workQueue?
答案 0 :(得分:5)
Sun内部创建线程的规则:
如果线程数小于corePoolSize
,请创建一个新线程来运行新任务。
如果线程数等于(或大于)corePoolSize
,则将任务放入队列。
如果队列已满,并且线程数小于maxPoolSize
,请创建一个新线程以运行任务。
如果队列已满,并且线程数大于或等于maxPoolSize
,请拒绝该任务。
你的情况是线程数达到maxPoolSize
的最后一个,即6,队列也已满(队列中的任务数为5),因此任务到来被拒绝并给出{{1} }。
答案 1 :(得分:1)
<property name="queueCapacity" value="5"/>
因此,要执行的“等待”任务的最大数量为5.在先前任务完成之前执行的任何进一步提交将导致TaskRejectException
此信息也存储在异常本身
中[java.util.concurrent.ThreadPoolExecutor@1f7911b [正在运行,泳池大小= 6,活动线程= 0,排队任务= 5,完成任务= 18]
答案 2 :(得分:0)
增加您的queueCapacity
:
<property name="queueCapacity" value="500"/>