一 概述

1.线程池产生背景

在多线程环境下,频繁地创建与销毁线程会耗费大量的系统资源,降低运行性能,因此产生了一种设计思想:将创建好的线程放到一个容器中,需要时从容器取得线程,使用完毕将线程归还容器,这样就可以重复利用线程,避免了重复创建与销毁造成的资源消耗,提高了性能。

2.什么是线程池?

元素:线程。
本质:容器。
设计目的:使得线程能够被重复使用,降低系统消耗。
一个以多个线程为元素、通过重复使用降低系统消耗的容器。

二 ThreadPoolExecutor

该类是线程池思想的核心类,继承关系如图。

一个代表性的构造方法;

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

1.coolPoolSize

核心池大小。这个数字是根据一般情况下并发访问的线程数目设定的。默认情况下,线程池创建完毕后,池中并没有线程,有任务到达以后才开始创建线程。

2.maximumPoolSize

线程池中允许出现的最大线程数。维护线程需要消耗系统资源,最大线程数目的设定既考虑高峰时期最大并发访问数量,也兼顾了系统性能。

3.keepAliveTime

这个参数针对的是超出核心池大小的多余线程。设定一个时间,如果多余线程空闲时间超过该值,线程会被终止。默认情况下,只有当线程数目大于核心池大小时才有效,如果allowCoreThreadTimeOut设定为true,当线程数目小于核心池大小时也有效。

4.unit

keepAliveTime的单位。

5.workQueue

一个阻塞队列,用来存储等待执行的任务。BlockingQueue有几个常用的实现类:

  • ArrayBlockingQueue:不常用。
  • LinkedBlockingQueue:常用。
  • SynchronousQueue:常用。

6.threadFactory

线程工厂,用来创建线程。

7.handler

当线程数目到达最大值时,拒绝处理任务时采取的策略。

三 执行过程

1.当线程数目小于核心数目时,每来一个任务就创建一个线程去执行该任务。
2.当线程数目大于等于核心数目时,首先尝试将新到达的任务添加到任务缓存队列中,若添加成功,等待空闲线程执行该任务,添加失败尝试创建新的线程处理该任务。
3.如果线程达到最大数目,新任务达到时会采取拒绝处理策略。

execute()是ThreadPoolExecutor的核心方法,下面对该源码进行分析:

public void execute(Runnable command) {if (command == null)throw new NullPointerException();/** Proceed in 3 steps:** 1. If fewer than corePoolSize threads are running, try to* start a new thread with the given command as its first* task.  The call to addWorker atomically checks runState and* workerCount, and so prevents false alarms that would add* threads when it shouldn't, by returning false.** 2. If a task can be successfully queued, then we still need* to double-check whether we should have added a thread* (because existing ones died since last checking) or that* the pool shut down since entry into this method. So we* recheck state and if necessary roll back the enqueuing if* stopped, or start a new thread if there are none.** 3. If we cannot queue task, then we try to add a new* thread.  If it fails, we know we are shut down or saturated* and so reject the task.*/int c = ctl.get();//workerCountOf(c)用于获取线程池中当前线程数目if (workerCountOf(c) < corePoolSize) {//addWorker(command,true)创建新的线程执行该任务if (addWorker(command, true))return;c = ctl.get();}//当线程数目大于等于corePoolSize时,首先尝试将任务添加到任务缓存队列中if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}//如果任务缓存队列已满,尝试创建新的线程else if (!addWorker(command, false))reject(command);}

addWorker(Runnable firstTask, boolean core)源码:

private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {........................................................................for (;;) {int wc = workerCountOf(c);//当core=true时,如果线程数目小于corePoolSize,程序继续执行,创建新线程;当core=false时,如果线程数目大于等于//maximumPoolSize,程序终止执行,返回false,不会创建新的线程。if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();  // Re-read ctlif (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 {//为任务创建一个新的线程w = new Worker(firstTask);..............................................} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;}

四 使用

通常不直接使用ThreadPoolExecutor的构造方法来创建对象,而是使用Executors的静态方法来创建对象。

newCachedThreadPool();

corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,使用SynchronousQueue作为任务缓存队列,如果线程池中没有可用的线程,每来一个任务创建一个线程。

newFixedThreadPool(int nThreads);

corePoolSize=nThreads,maximumPoolSize=nThreads,keepAliveTime=0s,使用LinkedBlockingQueue作为任务缓存队列。
线程池执行对象创创建完毕以后,将任务通过execute(Runnable command)方法提交给线程池执行对象即可。

参考:

http://www.cnblogs.com/dolphin0520/p/3932921.html

转载于:https://www.cnblogs.com/tonghun/p/7086342.html

线程池ThreadPoolExecutor相关推荐

  1. Java线程池ThreadPoolExecutor使用和分析

    Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) Java线程池ThreadPoolExecutor使用和分析(三 ...

  2. Python 线程池 ThreadPoolExecutor(二) - Python零基础入门教程

    目录 一.Python 线程池前言 二.Python 线程池 ThreadPoolExecutor 常用函数 1.线程池 as_completed 函数使用 2.线程池 map 函数使用 3.线程池 ...

  3. Python 线程池 ThreadPoolExecutor(一) - Python零基础入门教程

    目录 一.Python 线程池前言 二.Python 线程池原理 三.Python 线程池 ThreadPoolExecutor 函数介绍 四.Python 线程池 ThreadPoolExecuto ...

  4. Java线程池ThreadPoolExecutor的实例

    Java.util中的线程池和Spring框架对这个类的扩展 1.单独通过java里的ThreadPoolExecutor这个类,可以创建线程池,如果系统采用Spring框架设计,可以采用Thread ...

  5. java线程池执行器_Java线程池ThreadPoolExecutor的使用

    Java线程池ThreadPoolExecutor的使用 ThreadPoolExecutor就是我们用来实现线程的一个执行器,它实现了Excutor和ExecutorService接口.Excuto ...

  6. c++ 线程池_JAVA并发编程:线程池ThreadPoolExecutor源码分析

    前面的文章已经详细分析了线程池的工作原理及其基本应用,接下来本文将从底层源码分析一下线程池的执行过程.在看源码的时候,首先带着以下两个问题去仔细阅读.一是线程池如何保证核心线程数不会被销毁,空闲线程数 ...

  7. 线程池ThreadPoolExecutor的使用方法

    private static ExecutorService exec = new ThreadPoolExecutor(8, 8, 0L, TimeUnit.MILLISECONDS, new Li ...

  8. Java线程池—ThreadPoolExecutor

    2019独角兽企业重金招聘Python工程师标准>>> 为什么要使用线程池创建线程?     使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题 ...

  9. JUC(十)-线程池-ThreadPoolExecutor分析

    ThreadPoolExecutor 应用 & 源码解析 文章目录 ThreadPoolExecutor 应用 & 源码解析 一.线程池相关介绍 1.1 为什么有了JDK提供的现有的创 ...

  10. 线程池ThreadPoolExecutor使用简介

    2019独角兽企业重金招聘Python工程师标准>>> 一.简介  线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: Th ...

最新文章

  1. 深圳大学计算机暑期学校,The First Day-深度学习暑期学校
  2. 报名|首届中国智慧城市大数据开放创新应用大赛
  3. 内存泄漏分析 mat 使用 activity泄漏
  4. Hadoop配置SSH直接登录
  5. iOS中正则表达式的使用
  6. EXT中给时间控件设置默认值
  7. (三)通用视图(generic views)
  8. [mybatis]动态sql_sql_抽取可重用的sql片段
  9. java实现原数组根据下标分隔成两个子数组并且在原数组中交换两个子数组的位置...
  10. sql 删除数据_从零开始学SQL:是什么、如何安装、基本语法、表格(创建、删除、更新)、数据(插入、删除、更新)...
  11. 检测浏览器的关闭事件
  12. php libev扩展使用
  13. 红米k50 至尊版 解锁bl 获取root教程步骤
  14. 美团2015年校园招聘部分笔试题
  15. CodeForces 366C Dima and Salad
  16. 【主板上各种接口和附属部件科普】
  17. FACES纳新|2021春纳线上分享会等你来
  18. JavaScript/jQuery WebIM 及时聊天通信工具 本地客户端
  19. 《新学期,新Flag》乘风破浪
  20. 微信小程序开发.小程序入门(上)

热门文章

  1. 人脸检测--Face Detection with End-to-End Integration of a ConvNet and a 3D Model
  2. Java 批量文件不打包下载_【Java】Java批量文件打包下载zip
  3. C++显示转换、dynamic_cast重点
  4. 转载【C】堆区和栈区的区别
  5. 专转本计算机应用基础,江苏省专转本计算机应用基础模拟题
  6. What is OPcache
  7. 硬件加速_来试试微软神油灵不灵:更新驱动体验硬件加速GPU计划功能
  8. 七夕节马上到了,有对象的,无对象的必备神奇用Python做一个烟花秀
  9. wordpress php 7 速度优化,WordPress优化提速必做的6种操作代码篇
  10. matlab fir工具箱,用MATLAB信號處理工具箱進行FIR濾波器設計的三種方法