[Q&A] newFixedThreadPool
定义
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads,
nThreads,
0L, // 设置为0L,意味着多余的空闲线程会被立即终止。
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
[Q&A] FixedThreadPool
的execute()
方法的运行示意图
1)如果当前运行的线程数少于corePoolSize,则创建新线程来执行任务。
2)如果当前运行的线程数等于corePoolSize,将任务加入LinkedBlockingQueue。
3)线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行。
[Q&A] newFixedThreadPool
可能存在的问题
FixedThreadPool使用无界队列LinkedBlockingQueue
作为线程池的工作队列。使用无界队列作为工作队列会对线程池带来如下影响。
1)当线程池中的线程数达到corePoolSize
后,新任务将在无界队列中等待,因此线程池中的线程数不会超过corePoolSize
。
2)由于1
,使用无界队列时maximumPoolSize
将是一个无效参数。
3)由于1
和2
,使用无界队列时keepAliveTime
将是一个无效参数。
4)由于使用无界队列,运行中的FixedThreadPool(未执行方法shutdown()
或shutdownNow()
)不会拒绝任务(不会调用RejectedExecutionHandler.rejectedExecution
方法)。
-----------------------------------------------------------------------------读书笔记摘自 书名:Java并发编程的艺术 作者:方腾飞;魏鹏;程晓明
常见用途
线程任务
public class Task implements Runnable {
private final String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " → " + name + " Start Time = " + new Date());
processCommand();
System.out.println(Thread.currentThread().getName() + " → " + name + " End Time = " + new Date());
}
private void processCommand() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
固定线程数量线程池
public class FixThreadPool {
public static void main(String args[]) throws InterruptedException, ExecutionException {
System.out.println(Thread.currentThread().getName() + "线程: Start at: " + new Date());
ExecutorService exec = Executors.newFixedThreadPool(3);
for (int i = 1; i < 10; i++) {
System.out.println("添加了第" + i + "个任务类");
Thread.sleep(2);
exec.execute(new Task("线程名字" + i));
}
exec.shutdown();
System.out.println(Thread.currentThread().getName() + "线程: Finished all threads at:" + new Date() + ". isTerminated 判断次数 ");
}
}
执行结果分析
执行结果 |
---|
main线程: Start at: Fri May 19 21:29:50 CST 2023 |
添加了第1个任务类 |
添加了第2个任务类 |
添加了第3个任务类 |
添加了第4个任务类 |
添加了第5个任务类 |
pool-1-thread-1 → 线程名字1 Start Time = Fri May 19 21:29:50 CST 2023 |
pool-1-thread-2 → 线程名字2 Start Time = Fri May 19 21:29:50 CST 2023 |
pool-1-thread-3 → 线程名字3 Start Time = Fri May 19 21:29:50 CST 2023 |
添加了第6个任务类 |
添加了第7个任务类 |
添加了第8个任务类 |
添加了第9个任务类 |
main线程: Finished all threads at:Fri May 19 21:29:50 CST 2023. isTerminated 判断次数 |
pool-1-thread-2 → 线程名字2 End Time = Fri May 19 21:29:53 CST 2023 |
pool-1-thread-3 → 线程名字3 End Time = Fri May 19 21:29:53 CST 2023 |
pool-1-thread-3 → 线程名字5 Start Time = Fri May 19 21:29:53 CST 2023 |
pool-1-thread-2 → 线程名字4 Start Time = Fri May 19 21:29:53 CST 2023 |
pool-1-thread-1 → 线程名字1 End Time = Fri May 19 21:29:53 CST 2023 |
pool-1-thread-1 → 线程名字6 Start Time = Fri May 19 21:29:53 CST 2023 |
pool-1-thread-3 → 线程名字5 End Time = Fri May 19 21:29:56 CST 2023 |
pool-1-thread-3 → 线程名字7 Start Time = Fri May 19 21:29:56 CST 2023 |
pool-1-thread-1 → 线程名字6 End Time = Fri May 19 21:29:56 CST 2023 |
pool-1-thread-1 → 线程名字8 Start Time = Fri May 19 21:29:56 CST 2023 |
pool-1-thread-2 → 线程名字4 End Time = Fri May 19 21:29:56 CST 2023 |
pool-1-thread-2 → 线程名字9 Start Time = Fri May 19 21:29:56 CST 2023 |
pool-1-thread-2 → 线程名字9 End Time = Fri May 19 21:29:59 CST 2023 |
pool-1-thread-3 → 线程名字7 End Time = Fri May 19 21:29:59 CST 2023 |
pool-1-thread-1 → 线程名字8 End Time = Fri May 19 21:29:59 CST 2023 |
从控制台结果可以看出: |
线程池创建3 个线程来 执行这9 个任务,线程池大小为3 ,也就说同一时刻最多只有3 个线程能运行 |
主线程的执行与线程池里的线程分开,有可能主线程结束了,但是线程池还在运行 |
放入线程池的线程并不一定会按其放入的先后而顺序执行 |