在用jdk自带的jvm查看工具(bin/jvisualvm.exe) jvisualvm查看项目的运行状况的时候,发现Thread一只在增加(Thread dump),故进一步了解了一下ThreadPoolExecutor。
ThreadPoolExecutor 的 corePoolSize 的理解:
根据ThreadPoolExecutor的官方doc文档说明:When a new task is submitted in method execute(java.lang.Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle.
可以看出这个corePoolSize 的意思是说:当外部来了一个execute的请求,如果这时候正在运行状态的线程数 < corePoolSize 的时候,就会创建一个新的Thread去处理。但是需要注意的是,一个ThreadPoolExecutor 在创建之初,是不会立即初始化corePoolSize数量的Thread的,而是通过外部request来一个一个的创建,当达到corePoolSize数目之后,就会维持至少corePoolSize数目的Thread在pool中,哪怕他们都处于空闲状态(idle).
通过例子更好理解一点,下面用ThreadPoolExecutor的子类ScheduledThreadPoolExecutor做例子:
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class MyTest { private static AtomicInteger sequenceNumGenerator = new AtomicInteger(); public static void main(String[] args) throws Exception { //pool with corePoolSize 10 ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(10); //print the active thread and total thread num when pool created System.out.println(pool.getActiveCount()); System.out.println(pool.getPoolSize()); //execute 2 task pool.execute(getTask()); pool.execute(getTask()); //print the active thread and total thread num when tasks not finish System.out.println(pool.getActiveCount()); System.out.println(pool.getPoolSize()); //wait to ensure all tasks finish Thread.sleep(3000); //print the active thread and total thread num when all tasks finish System.out.println(pool.getActiveCount()); System.out.println(pool.getPoolSize()); //shutdown thread pool pool.shutdown(); } private static Runnable getTask(){ return new Runnable(){ @Override public void run() { int sequenceNum = sequenceNumGenerator.incrementAndGet(); System.out.println("begin task " + sequenceNum); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("finish task " + sequenceNum); } }; } }
根据结果可以看出:
ThreadPool在初始化的时候,active的thread 和 pool中的thread总数量都是0.也就是说没有初始化任何的thread
执行2个task,并且在task结束之前, active的thread 和 pool中的thread总数量都是2
在执行了2个task之后,并且在task都结束了之后, active的thread 和 pool中的thread总数量分别是0和2
这样就很清楚了,ThreadPoolExecutor的corePoolSize 数量的thread并不是在ThreadPoolExecutor创建的时候就理解初始化的,而是慢慢的通过外部的调用(例如调用execute)来一个一个的创建,最终达到corePoolSize 数量。
下面修改一下corePoolSize,让执行的task数量大于corePoolSize:
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class MyTest { private static AtomicInteger sequenceNumGenerator = new AtomicInteger(); public static void main(String[] args) throws Exception { //pool with corePoolSize 10 ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(3); //print the active thread and total thread num when pool created System.out.println(pool.getActiveCount()); System.out.println(pool.getPoolSize()); //execute 2 task pool.execute(getTask()); pool.execute(getTask()); pool.execute(getTask()); pool.execute(getTask()); //print the active thread and total thread num when tasks not finish System.out.println(pool.getActiveCount()); System.out.println(pool.getPoolSize()); //wait to ensure all tasks finish Thread.sleep(4000); //print the active thread and total thread num when all tasks finish System.out.println(pool.getActiveCount()); System.out.println(pool.getPoolSize()); //shutdown thread pool pool.shutdown(); } private static Runnable getTask(){ return new Runnable(){ @Override public void run() { int sequenceNum = sequenceNumGenerator.incrementAndGet(); System.out.println("begin task " + sequenceNum); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("finish task " + sequenceNum); } }; } }
就会发现ThreadPoolExecutor在所以task完成之后,会维持corePoolSize数量的thread在threadpool中,哪怕这些task已经完成工作,处于空闲状态(idle)
相关推荐
说说你对ThreadPoolExecutor的理解.docx
Android中的线程池ThreadPoolExecutor解决了单线程下载数据的效率慢和线程阻塞的的问题,它的应用也是优化...<span xss=removed>ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
ThreadPoolExecutor源码解析.pdf
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long
ThreadPoolExecutor源码解析.md
ThreadPoolExecutor使用和思考
(转)线程池:java_util_ThreadPoolExecutor 比较详细的介绍了ThreadPoolExecutor用法与属性
ThreadPoolExecutor线程池,有详尽介绍,本人进行过测试,可以使用
在《阿里巴巴java开发手册》中...另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。
线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor...
一个关于java 线程池的例子,也适合android
ThreadPoolExecutor的使用和Android常见的4种线程池使用介绍
1.资源简介:PyQt5中使用多线程模块QThread解决了PyQt5界面程序执行比较耗时操作时,程序卡顿出现的无响应以及界面输出无法实时显示的问题,采用线程池ThreadPoolExecutor解决了ping多个IP多任务耗时问题。...
主要介绍了Java ThreadPoolExecutor的参数深入理解的相关资料,需要的朋友可以参考下
线程池的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,那么超出数量的线程排队等候,等其他线程执行完毕再从队列中取出任务来执行。...
NULL 博文链接:https://bijian1013.iteye.com/blog/2284676
线程池原理-ThreadPoolExecutor源码解析 1.构造方法及参数 2.阻塞对列: BlockingQueue 3.线程工厂: DefaultThreadFactory 4.拒绝策略: RejectedExecutionHandler 5.执行线程 Executor
死磕ThreadPoolExecutor线程池.pdf!!死磕ThreadPoolExecutor线程池.pdf死磕ThreadPoolExecutor线程池.pdf死磕ThreadPoolExecutor线程池.pdf
JDK1[1].5中的线程池(ThreadPoolExecutor)使用简介
介绍ThreadPoolExecutor中池和queue配合使用的机制