Java并发之线程池(三)
来源:互联网 发布:2k17德拉蒙德格林数据 编辑:程序博客网 时间:2024/05/19 12:39
一、前言
2016年即将过去,要抓紧时间,夯实java基础知识部分,为以后学习的新的知识做准备。
二、线程池基本原理图
三、ThreadPoolExecutor的内部结构
1.Worker在里面是一个核心的内部类
private final class Worker extends AbstractQueuedSynchronizer implements Runnable { /** * This class will never be serialized, but we provide a * serialVersionUID to suppress a javac warning. */ private static final long serialVersionUID = 6138294804551838833L; /** Thread this worker is running in. Null if factory fails. */ final Thread thread; /** Initial task to run. Possibly null. */ Runnable firstTask; /** Per-thread task counter */ volatile long completedTasks; //... }
构造方法
//由线程工厂创建一个任务线程 Worker(Runnable firstTask) { setState(-1); // inhibit interrupts until runWorker this.firstTask = firstTask; this.thread = getThreadFactory().newThread(this); }部分方法:
/** 将由ThreadPoolExecutor的runWorker执行*/ public void run() { runWorker(this); }2.类的属性
// 线程池的控制状态(用来表示线程池的运行状态(整形的高3位)和运行的worker数量(低29位) private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); // 29位的偏移量 private static final int COUNT_BITS = Integer.SIZE - 3; // 最大容量(2^29 - 1) private static final int CAPACITY = (1 << COUNT_BITS) - 1; // runState is stored in the high-order bits // 线程运行状态,总共有5个状态,需要3位来表示(所以偏移量的29 = 32 - 3) private static final int RUNNING = -1 << COUNT_BITS; private static final int SHUTDOWN = 0 << COUNT_BITS; private static final int STOP = 1 << COUNT_BITS; private static final int TIDYING = 2 << COUNT_BITS; private static final int TERMINATED = 3 << COUNT_BITS; //阻塞队列 private final BlockingQueue<Runnable> workQueue; //主方法重入锁 private final ReentrantLock mainLock = new ReentrantLock(); //工作线程集合 private final HashSet<Worker> workers = new HashSet<Worker>(); //终止条件 private final Condition termination = mainLock.newCondition(); //最大池大小 private int largestPoolSize; //完成任务的数量 private long completedTaskCount; //线程工厂 private volatile ThreadFactory threadFactory; //拒绝处理器接口 private volatile RejectedExecutionHandler handler; //保持的时间 private volatile long keepAliveTime; //允许线程的超时时间 private volatile boolean allowCoreThreadTimeOut; //核心线程池的大小 private volatile int corePoolSize; //最大线程池大小 private volatile int maximumPoolSize; //默认拒绝处理器 private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
3.构造方法
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler); } public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,threadFactory, defaultHandler); } public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), handler); } public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
4.部分方法
4.1 public void execute(Runnable command)方法
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); /* * 进行下面三步 * * 1. 如果运行的线程小于corePoolSize,则尝试使用用户定义的Runnalbe对象创建一个新的线程 * 调用addWorker函数会原子性的检查runState和workCount,通过返回false来防止在不应 * 该添加线程时添加了线程 * 2. 如果一个任务能够成功入队列,在添加一个线城时仍需要进行双重检查(因为在前一次检查后 * 该线程死亡了),或者当进入到此方法时,线程池已经shutdown了,所以需要再次检查状态, * 若有必要,当停止时还需要回滚入队列操作,或者当线程池没有线程时需要创建一个新线程 * 3. 如果无法入队列,那么需要增加一个新线程,如果此操作失败,那么就意味着线程池已经shut * down或者已经饱和了,所以拒绝任务 */ int c = ctl.get(); if (workerCountOf(c) < corePoolSize) {//小于核心线程池大小 if (addWorker(command, true))//新增Worker return; c = ctl.get();//再次获取线程状态 } // 当线程池中的任务数量 >= "核心池大小"时, // 而且,"线程池处于允许状态"时,则尝试将任务添加到阻塞队列中。 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); // 否则,如果"线程池中任务数量"为0,则通过addWorker(null, false) //尝试新建一个线程,新建线程对应的任务为null。 else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false))//添加线程失败 //拒绝执行 reject(command); }4.2private boolean addWorker(Runnable firstTask, boolean core)添加工作线程
private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { int c = ctl.get();//// 获取ctl对应的int值。该int值保存了"线程池中任务的数量"和"线程池状态"信息 int rs = runStateOf(c);//获取线程池的状态 // 对队列和状态进行检查 if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false; for (;;) { int wc = workerCountOf(c);//线程池任务数量 if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize))//超过容量返回false return false; if (compareAndIncrementWorkerCount(c))//工作线程数量增加 break retry; c = ctl.get(); // Re-read ctl再次获取线程池信息 if (runStateOf(c) != rs)//判断状态 continue retry; // else CAS failed due to workerCount change; retry inner loop } } boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock; w = new Worker(firstTask);//添加工作线程 final Thread t = w.thread; if (t != null) { mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. //获取线程池的信息再次判断 int c = ctl.get(); int rs = runStateOf(c); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); workers.add(w);//添加到工作线程集合 int s = workers.size(); if (s > largestPoolSize)//设置最大线程池大小 largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } if (workerAdded) {//添加成功 t.start();//运行 workerStarted = true;//设置工作线程的状态 } } } finally { if (! workerStarted)//如果失败 addWorkerFailed(w);//线程集合将会移除工作线程并将线程池的数量减1 } return workerStarted;//返回工作线程运行的状态 }
4.3private void addWorkerFailed(Worker w) 线程启动失败
private void addWorkerFailed(Worker w) 线程启动失败 private void addWorkerFailed(Worker w) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //线程集合将会移除工作线程并将线程池的数量减1 if (w != null) workers.remove(w); decrementWorkerCount(); tryTerminate(); } finally { mainLock.unlock(); } }4.4线程池关闭相关的方法
/** 依次的关闭线程,之前已提交的任务将会执行完成,但是不会接受新的任务, 如果已关闭再次调用不会有额外的影响。 */ public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess();//检查关闭的权限 advanceRunState(SHUTDOWN);//设置关闭 interruptIdleWorkers();中断空闲的工作线程 onShutdown(); // hook for ScheduledThreadPoolExecutor } finally { mainLock.unlock(); } tryTerminate(); } /** 试图去停止所有的运行的线程,终止所有等待的任务,并将等待的任务用集合返回, 清空任务队列的信息并返回。 */ public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess();//检查关闭权限 advanceRunState(STOP);设置停止 interruptWorkers();//中断所有线程 tasks = drainQueue();//释放队列并返回未执行的任务 } finally { mainLock.unlock(); } tryTerminate(); return tasks; } public boolean isShutdown() { return ! isRunning(ctl.get()); //检查线程池是否关闭 }
//中断所有空闲线程 private void interruptIdleWorkers(boolean onlyOne) { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) { Thread t = w.thread; if (!t.isInterrupted() && w.tryLock()) { try { t.interrupt();//中断线程 } catch (SecurityException ignore) { } finally { w.unlock(); } } if (onlyOne) break; } } finally { mainLock.unlock(); } } //清空队列并返回 private List<Runnable> drainQueue() { BlockingQueue<Runnable> q = workQueue; List<Runnable> taskList = new ArrayList<Runnable>();//返回list集合 q.drainTo(taskList); if (!q.isEmpty()) { for (Runnable r : q.toArray(new Runnable[0])) { if (q.remove(r))//移除 taskList.add(r); } } return taskList; }
//中断所有线程 private void interruptWorkers() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) w.interruptIfStarted(); } finally { mainLock.unlock(); } }
四、总结
线程池的设计非常的好,更重要的是理解其中的设计思想和原理。
0 0
- Java并发之线程池(三)
- Java 并发编程之线程池的使用 (三)
- Java 并发编程之线程池的使用 (三)
- 【Java】并发之线程池
- 【Java】并发之线程池
- java并发之线程池
- Java线程并发库之线程池
- java多线程与并发之java线程简介(三)
- Java并发之线程
- Java并发之线程
- Java 1.5并发包之三:线程池实现之Fork/Join框架
- Java并发学习之三——线程的中断
- java编程思想笔记-并发之线程协作(三)
- Java并发之串行线程池
- Android 并发二三事之Java线程池
- Java并发之线程池(一)
- Java并发之线程池Executors(二)
- Java并发编程之线程池
- 12.24
- BZOJ 4695
- tbschedule源码学习
- 光纤通信原理
- gcc 软连接
- Java并发之线程池(三)
- 2016年12月
- 法律网推荐(二) 用Pig进行数据预处理
- C语言实验——大小写转换
- POJ 2068 Nim 已翻译
- 用java调用VS2010 debug生成的.exe文件
- android控件中的一些重要属性(一)
- 几种使用了CNN(卷积神经网络)的文本分类模型
- 新闻管理系统的设计与实现