java - 我正在使用 java 线程池,并且出现了一个我无法理解的错误

标签 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

谁能告诉我,为什么当我将任务放入线程池时,poll首先将任务放入workQueue?

最佳答案

Sun 内部创建线程的规则:

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

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

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

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

您的情况是最后一种情况,其中线程数已达到 maxPoolSize 即 6 并且队列也已满(队列中的任务数为 5),因此任务被拒绝并给出TaskRejectedException

关于java - 我正在使用 java 线程池,并且出现了一个我无法理解的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29118689/

相关文章:

java - 如何向 Tapestry Grid 添加额外的行?

java - 我正在打印我的 linkedList 但第一个元素没有打印,这是为什么

java - 在 CMU Sphinx (pocketsphinx) 中使用 JSGF 语法代替 DMP 语言模型(使用 -jsgf 代替 -lm)

java - Android Studio - 应用程序中使用的库项目如何遵循 app-release.apk

java - 如何使用 IntelliJ IDEA 计算 Java 代码行数?

java - 复合主键太长?

java - 如何在进程终止时执行操作?

java - 使用 Firebase Java API 检索/格式化数据的最佳方式

java - 在 JUnit 中断言异常

java - 批量插入期间仅插入一半的二进制文档