我正在使用java theadpool,但是我得到了一个我无法理解的错误

时间:2015-03-18 09:45:46

标签: java

<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?

3 个答案:

答案 0 :(得分:5)

Sun内部创建线程的规则:

  1. 如果线程数小于corePoolSize,请创建一个新线程来运行新任务。

  2. 如果线程数等于(或大于)corePoolSize,则将任务放入队列。

  3. 如果队列已满,并且线程数小于maxPoolSize,请创建一个新线程以运行任务。

  4. 如果队列已满,并且线程数大于或等于maxPoolSize,请拒绝该任务。

  5. 你的情况是线程数达到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"/>