Java concurrency线程池之线程池原理(一)_动力节点Java学院整理
threadpoolexecutor简介
threadpoolexecutor是线程池类。对于线程池,可以通俗的将它理解为"存放一定数量线程的一个线程集合。线程池允许若个线程同时允许,允许同时运行的线程数量就是线程池的容量;当添加的到线程池中的线程超过它的容量时,会有一部分线程阻塞等待。线程池会通过相应的调度策略和拒绝策略,对添加到线程池中的线程进行管理。"
threadpoolexecutor数据结构
threadpoolexecutor的数据结构如下图所示:
各个数据在threadpoolexecutor.java中的定义如下:
// 阻塞队列。 private final blockingqueue<runnable> workqueue; // 互斥锁 private final reentrantlock mainlock = new reentrantlock(); // 线程集合。一个worker对应一个线程。 private final hashset<worker> workers = new hashset<worker>(); // “终止条件”,与“mainlock”绑定。 private final condition termination = mainlock.newcondition(); // 线程池中线程数量曾经达到过的最大值。 private int largestpoolsize; // 已完成任务数量 private long completedtaskcount; // threadfactory对象,用于创建线程。 private volatile threadfactory threadfactory; // 拒绝策略的处理句柄。 private volatile rejectedexecutionhandler handler; // 保持线程存活时间。 private volatile long keepalivetime; private volatile boolean allowcorethreadtimeout; // 核心池大小 private volatile int corepoolsize; // 最大池大小 private volatile int maximumpoolsize;
1. workers
workers是hashset<work>类型,即它是一个worker集合。而一个worker对应一个线程,也就是说线程池通过workers包含了"一个线程集合"。当worker对应的线程池启动时,它会执行线程池中的任务;当执行完一个任务后,它会从线程池的阻塞队列中取出一个阻塞的任务来继续运行。
wokers的作用是,线程池通过它实现了"允许多个线程同时运行"。
2. workqueue
workqueue是blockingqueue类型,即它是一个阻塞队列。当线程池中的线程数超过它的容量的时候,线程会进入阻塞队列进行阻塞等待。
通过workqueue,线程池实现了阻塞功能。
3. mainlock
mainlock是互斥锁,通过mainlock实现了对线程池的互斥访问。
4. corepoolsize和maximumpoolsize
corepoolsize是"核心池大小",maximumpoolsize是"最大池大小"。它们的作用是调整"线程池中实际运行的线程的数量"。
例如,当新任务提交给线程池时(通过execute方法)。
-- 如果此时,线程池中运行的线程数量< corepoolsize,则创建新线程来处理请求。
-- 如果此时,线程池中运行的线程数量> corepoolsize,但是却< maximumpoolsize;则仅当阻塞队列满时才创建新线程。
如果设置的 corepoolsize 和 maximumpoolsize 相同,则创建了固定大小的线程池。如果将 maximumpoolsize 设置为基本的*值(如 integer.max_value),则允许池适应任意数量的并发任务。在大多数情况下,核心池大小和最大池大小的值是在创建线程池设置的;但是,也可以使用 setcorepoolsize(int) 和 setmaximumpoolsize(int) 进行动态更改。
5. poolsize
poolsize是当前线程池的实际大小,即线程池中任务的数量。
6. allowcorethreadtimeout和keepalivetime
allowcorethreadtimeout表示是否允许"线程在空闲状态时,仍然能够存活";而keepalivetime是当线程池处于空闲状态的时候,超过keepalivetime时间之后,空闲的线程会被终止。
7. threadfactory
threadfactory是threadfactory对象。它是一个线程工厂类,"线程池通过threadfactory创建线程"。
8. handler
handler是rejectedexecutionhandler类型。它是"线程池拒绝策略"的句柄,也就是说"当某任务添加到线程池中,而线程池拒绝该任务时,线程池会通过handler进行相应的处理"。
综上所说,线程池通过workers来管理"线程集合",每个线程在启动后,会执行线程池中的任务;当一个任务执行完后,它会从线程池的阻塞队列中取出任务来继续运行。阻塞队列是管理线程池任务的队列,当添加到线程池中的任务超过线程池的容量时,该任务就会进入阻塞队列进行等待。
线程池调度
我们通过下面的图看看下面线程池中任务的调度策略,加深对线程池的理解。
图-01:
图-02:
说明:
在"图-01"中,线程池中有n个任务。"任务1", "任务2", "任务3"这3个任务在执行,而"任务3"到"任务n"在阻塞队列中等待。正在执行的任务,在workers集合中,workers集合包含3个worker,每一个worker对应一个thread线程,thread线程每次处理一个任务。
当workers集合中处理完某一个任务之后,会从阻塞队列中取出一个任务来继续执行,如图-02所示。图-02表示"任务1"处理完毕之后,线程池将"任务4"从阻塞队列中取出,放到workers中进行处理。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Java concurrency线程池之线程池原理(一)_动力节点Java学院整理
-
Java concurrency线程池之线程池原理(二)_动力节点Java学院整理
-
Java concurrency之CountDownLatch原理和示例_动力节点Java学院整理
-
Java class文件格式之常量池_动力节点Java学院整理
-
Java concurrency线程池之线程池原理(四)_动力节点Java学院整理
-
Java concurrency线程池之线程池原理(三)_动力节点Java学院整理
-
Java concurrency线程池之Callable和Future_动力节点Java学院整理
-
Java concurrency之公平锁(一)_动力节点Java学院整理
-
Java concurrency之CountDownLatch原理和示例_动力节点Java学院整理
-
Java concurrency线程池之线程池原理(二)_动力节点Java学院整理