JAVA并发编程之线程池ThreadPoolExcutor
Executor接口
|
|
Executor提供了操作Runnable的接口,我们可以直接执行Runnable的方法,也可以创建Thread来执行Runnable,也可以根据实际情况把Runnable放入队列中按顺序执行。
ExecutorService接口
|
|
AbstractExecutorService抽象类
AbstractExecutorService实现了ExecutorService的submit(),invokeAny()、invokeAll()方法。
|
|
ThreadPoolExecutor实现类
线程池的状态、数量
|
|
构造函数
|
|
任务的创建
|
|
任务的创建总结:
当前线程池中的数量小于corePoolSize,创建并添加的任务。
当前线程池中的数量大于等于corePoolSize,缓冲队列workQueue未满,那么任务被放入缓冲队列、等待任务调度执行。
当前线程池中的数量大于等corePoolSize,缓冲队列workQueue已满,并且线程池中的数量小于maximumPoolSize,新提交任务会创建新线程执行任务。
*果当前线程池中的数量大于等corePoolSize,缓冲队列workQueue已满,并且线程池中的数量等于maximumPoolSize,新提交任务由Handler处理。
不管什么条件,添加任务的过程总是不停的检查来确保线程池是正常状态,否则不会添加任务。
任务执行
想要看线程是如何运行的就必须看一下Worker的构造函数
|
|
下面详细分析一下runWorker
|
|
下面看看getTask是如何从堵塞队列取出任务的
Executors 线程池的配置
Executors在这里可以看做是一个工厂,生成不同的线程池,根据参数的不同生成不同的ThreadPoolExecutor:
创建一个线程数目固定的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理
|
|
创建一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行
|
|
创建一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁
|
|
创建一个有定时功能的线程池,配置corePoolSize,无界延迟阻塞队列DelayedWorkQueue;
|
|
到这里,线程池的使用我们已经简单的了解了,ScheduledThreadPoolExecutor定时线程池与创建不同线程池时使用的QUeue在别的文章中分析。