原理篇:深度解析Java 线程池的实现原理
https://heapdump.cn/monographic/detail/35/4392001
在实际的开发中,我们需要根据任务的性质(IO是否频繁?)来决定我们创建的核心的线程数的大小,实际上可以从以下的一个角度来分析:- 任务的性质:CPU密集型任务、IO密集型任务和混合型任务;
- 任务的优先级:高、中和低;
- 任务的执行时间:长、中和短;
- 任务的依赖性:是否依赖其他系统资源,如数据库连接;
CPU密集型任务应配置尽可能小的线程,如配置 Ncpu+1个线程的线程池。(可以通过Runtime.getRuntime().availableProcessors()来获取CPU物理核数)
IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如 2*Ncpu。
混合型的任务,如果可以拆分,将其拆分成一个CPU密集型任务一个IO密集型任务,只要这两个任务执行的时间相差不是太大,那么分解后执行的吞吐量将高于串行执行的吞吐量。 如果这两个任务执行时间相差太大,则没必要进行分解。可以通过 Runtime.getRuntime().availableProcessors() 方法获得当前设备的CPU个数。 优先级不同的任务可以使用优先级队列 PriorityBlockingQueue来处理。它可以让优先级高的任务先执行(注意:如果一直有优先级高的任务提交到队列里,那么优先级低的任务可能永远不能执行)