<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 内部创建线程的规则:
如果线程数小于
corePoolSize
,则创建一个新线程来运行新任务。如果线程数等于(或大于)
corePoolSize
,则将任务放入队列中。如果队列已满,并且线程数小于
maxPoolSize
,则创建一个新线程来运行任务。如果队列已满,并且线程数大于或等于
maxPoolSize
,则拒绝任务。
您的情况是最后一种情况,其中线程数已达到 maxPoolSize
即 6 并且队列也已满(队列中的任务数为 5),因此任务被拒绝并给出TaskRejectedException
。
关于java - 我正在使用 java 线程池,并且出现了一个我无法理解的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29118689/