java线程池ThreadPoolExecutor理解
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
熟悉这四种线程池,首先 先了解ThreadPoolExecutor
ThreadPoolExecutor中定义了以下几个属性比较重要
corePoolSize:线程池中的线程数量,线程池中默认开启几个线程处理 任务队列中的任务
(注:这个并不是固定的,根据队列(workQueue)的不同实现类型而改变)
maximumPoolSize:线程池中的最大线程数量,这个属性感觉和上面的corePoolSize冲突,明明上面定义了线程数据了,怎么这里又控制了
最大线程数量,其实 一样和 上面提到的一样(根据队列(workQueue)的不同实现类型 ,需要用到该属性进行相应的 任务拒绝策略)
keepAliveTime;//超过corePoolSize的空闲线程,在多长时间内会被销毁
TimeUnit unit;//keepAliveTime的单位
BlockingQueue<Runnable> workQueue:任务队列,被提交的但尚未被执行的任务
主要有以下几种实现类型
SynchronousQueue:直接提交的队列,该队列没有容量,每一个擦入操作都要对应一个相应的删除操作,反之每个删除操作对应相应的插入操作。
SynchronousQueue不保存任务,它总是将任务提交给线程执行,如果没有空闲的进程,则尝试创建新的进程,如果进程
已达到maximumPoolSize设置的最大线程数,则执行拒绝策略
ArrayBlockingQueue:有界任务队列,ArrayBlockingQueue的构造函数必须带一个容量参数(例如n),表示该队列的最大容量。
当有新任务执行时,这个定义当前线程数为t,构造函数的容量参数为n,当前队列长度为l
1.t<corePoolSize时,创建新的线程之心
2.t>corePoolSize且l<n时,插入到任务队列,等待空闲线程执行
3.t>corePoolSize且l>=n时,创建新的线程执行新任务
4.t>maximumPoolSize时,执行拒绝策略。
LinkedBlockingQueue:无界任务队列,当有新任务执行时,如果线程池中线程数小于corePoolSize则创建新的线程,否则进入队列等待。
如果没有任务创建速度和处理速度差异很大,无界队列会保持快速增长,直到耗尽系统内存
PriorityBlockingQueue:优先级队列,可以控制任务的执行先后顺序,是一个特殊的无界队列。无论有界的队列无界的队列,都是按照先进先出算法
处理任务(絮叨),而该队列破例可以根据任务自身的优先级顺序先后执行。
ThreadFactory threadFactory//线程工厂,用于创建线程,一般默认
RejectedExecutionHandler handler;//拒绝策略,当任务太多来不及处理,如何拒绝任务
JDK内置的拒绝策略如下:
AbortPolity策略:该策略会直接抛出异常,阻止系统正常工作
CallerRunsPolity策略:只要线程为关闭,该策略直接在调用者线程中,运行当前被丢弃的任务
DiscardOledstPolicy策略:该策略将丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
DiscardPlicy 策略:该策略默默的丢弃无法处理的任务,不予任务处理。
如果以上策略不能满足实际应用需求,可以扩展RejectedExecutionHandler 接口
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
其中,r为请求执行的任务,executor为当前线程池。
了解了ThreadPoolExecutor的上述属性,然后分析Executors提供四种线程池就很简单了
Executors.newFixedThreadPool(nThreads)
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
返回了一个corePoolSize, maximumPoolSize大小相等并且使用了LinkedBlockingQueue任务队列的线程池,因为对于固定大小的线程池而言,不存在线程数量的动态
变化,因此corePoolSize,和maximumPoolSize可以相等,同时它使用无界队列存放无法立即执行的任务,当任务提交非常频繁的时候,该队列可能迅速膨胀,从而耗尽
系统资源。
Executors.newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
返回单线程的线程池,是newFixedThreadPool()方法的一种退化,只是简单的将线程池的线程数量设置为1
Executors.newCachedThreadPool()
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
返回corePoolSize为0 maximumPoolSize无穷大的线程池,这意味着在没有任务时,该线程内无线程,而当任务被提交时,该线程池会使用空闲的线程执行任务,若无空闲
线程,则将任务加入SynchronousQueue队列,而SynchronousQueue队列是一种直接提交的队列,它总会迫使线程池增加新的线程执行任务,当任务执行完毕后,
由于corePoolSize为0,因此空线程又会在指定时间内(60s)被回收。
对于newCachedThreadPool(),如果同时又大量任务被提交,而任务的执行又不那么快时,那么系统便会开启等量的线程处理,这样的做法可能会很快耗尽系统的资源。
java线程池ThreadPoolExecutor理解的更多相关文章
- Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java线程池ThreadPoolExecutor使用和分析(一)
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java线程池ThreadPoolExecutor类源码分析
前面我们在java线程池ThreadPoolExecutor类使用详解中对ThreadPoolExector线程池类的使用进行了详细阐述,这篇文章我们对其具体的源码进行一下分析和总结: 首先我们看下T ...
- java线程池ThreadPoolExecutor使用简介
一.简介线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:ThreadPoolExecutor(int corePoolSize, int m ...
- 转:JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue
从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构 ...
- 干货,阿里P8浅谈对java线程池的理解(面试必备)
线程池的概念 线程池由任务队列和工作线程组成,它可以重用线程来避免线程创建的开销,在任务过多时通过排队避免创建过多线程来减少系统资源消耗和竞争,确保任务有序完成:ThreadPoolExecutor ...
- Java 线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
- Java 线程池(ThreadPoolExecutor)原理解析
在我们的开发中“池”的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 有关java线程技术文章还可以推荐阅读:<关于java多线程w ...
随机推荐
- 【转载】Linux 信号列表
转自:http://blog.csdn.net/muge0913/article/details/7322710 信号及其简介 信号是一种进程通信的方法,他应用于异步事件的处理.信号的实现是一种软中断 ...
- 访问本地json文件因跨域导致的问题
我使用jquery的getJSON的方法获取本地的json文件,并进行操作,获取json 数据代码如下: $.getJSON("invite_panel.json",functio ...
- [IOS] 利用@IBInspectable
某些uiview中设置 这个关键字 IBInspectable 可以让其设置的属性,在右侧的属性栏目里面进行直接设置, 这是最近看了一下wwdc的一个视频学习到的,可以方便的进行 UI的测试,
- Web 开发基础
C/S:winform WPF 数据是存在其它的电脑上或服务器上需要从服务器上下载相应的数据,在本地电脑上的客户端里进行加工 数据加工的过程是在用户电脑上执行,会对用户的电脑配置有所要求 B/S: ...
- Sublime 常用插件简介
Sublime 常用插件简介 emmet: 前端必备神器.花个十几分钟学下Emmet语法 ,就可以极大提高web开发者HTML和CSS工作效率啦.一句话,牛逼---必备 CSS3: CSS3语法高 ...
- android删除无用资源文件的python脚本
随着android项目的进行,如果没有及时删除无用的资源时安装包会越来越大,是时候整理一下废弃资源缩小压缩包了,少年! 其实判断一个资源(drawable,layout)是否没有被使用很简单,文件名( ...
- 提倡IT从业人员终身学习
经常听身边的团队成员抱怨,今天太累了,回到家连动都不想动;这形成了目前圈子里大多从业者的生活常态. 但有一部分人,在团队里身居要职,薪水不少拿却工作不那么累,你想过他们么? 答案很简单,人家会学习,而 ...
- Linux用过的命令
-上传sudo -u b2b rz--创建文件夹sudo -u b2b mkdir--copysudo -u b2b cp /b2b/apache-tomcat-7.0.64/matt/DqN017S ...
- 关于IOS音频的开发积累
1.设置类别,表示该应用同时支持播放和录音 OSStatus error; UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord; ...
- 纯CSS实现下拉菜单及下拉容器等(纯CSS实现导航条及导航下拉容器)
虽然网上类似甚至相同的案例有很多,但是我还是写下,以记下笔记,也可供大家参考 希望大家可以指导批评~~ 首先我们以列表ul li 来开始我们菜单也可以说导航条的制作: 在页面中我们首先构建以下XHTM ...