我在实践中经历了Java Concurrency,并在8.3.1 Thread Creation and Teardown中找到了一个声明。下面是声明 - “即使没有要执行的任务,实现也会尝试将池维持在此大小,并且除非工作队列已满,否则不会创建比此更多的线程。”为了验证相同,我写了一个小代码
package com.executor;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyJobSubmitterThread extends Thread {
public static ExecutorService objExecutorService = new ThreadPoolExecutor(0, 1, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(2));
public static int counter = 1;
@Override
public void run() {
//Using Runnable
while(!objExecutorService.isShutdown()){
try{
objExecutorService.execute(new RandomNumberGenerator());
if(counter > 10){
objExecutorService.shutdownNow();
if(objExecutorService.isTerminated()){
System.out.println("Runnable - Terminated");
}
//objExecutorService.execute(new RandomNumberGenerator());
}
int objBlockingQueueSize = ((ThreadPoolExecutor)objExecutorService).getQueue().size();
++counter;
}catch (RejectedExecutionException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
故意不要将RandomNumberGenerator类的代码放在此问题的上下文中。
根据上面引用的语句,除非第三个任务被提交到队列,否则不应该创建和启动线程,但是与之相反,线程被创建并启动。当线程在10秒后死亡保持活着的时间,它刚刚在提交作业时创建。当我查看Java 1.7源代码中的execute方法代码时,它就像
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
有人可以解释为什么代码的行为与JCIP书中的陈述不同,反之亦然?我在这里错过了一点吗?
答案 0 :(得分:2)
本书中的陈述是准确的,但需要注意的是ThreadPoolExecutor
确保在有工作要做的时候至少有1个线程正在运行(即corePoolSize == 0是特殊情况)。
答案 1 :(得分:0)
您将核心池大小设置为0,将最大池大小设置为1.这意味着它最多只有一个线程来执行任务。并且由于线程数大于核心池大小(1> 0),因此该线程在保持空闲以保持活动时间之后将被移除。所以我认为情况正常。
ThreadPoolExecutor 尝试保持线程数等于核心池大小,如果线程数大于核心池大小则删除空闲线程并每次创建新线程,直到达到核心池大小。