Java Executors小结
一
Executors提供了一系列工厂方法用于创先线程池
ThreadPoolExecutor线程池的具体实现类,一般用的各种线程池都是基于这个类实现的
返回的线程池都实现了ExecutorService 接口
二
corePoolSize:线程池的核心线程数,默认情况下可以一直存活。可以通过设置allowCoreThreadTimeOut为True,此时 核心线程数就是0,此时keepAliveTime控制所有线程的超时时间。
maximumPoolSize:线程池允许的最大线程数;
keepAliveTime: 指的是空闲线程结束的超时时间;
unit:是一个枚举,表示 keepAliveTime 的单位;
workQueue:表示存放任务的BlockingQueue
BlockingQueue:是java.util.concurrent下的主要用来控制线程同步的工具。如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒。同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作。BlockingQueue常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。BlockingQueue就是生产者存放元素的容器,而消费者也只从容器里拿元素。
ArrayBlockingQueue:基于数组、有界,按 FIFO(先进先出)对元素进行排序
LinkedBlockingQueue:基于链表,按FIFO (先进先出)对元素进行排序
吞吐量通常要高于 ArrayBlockingQueue
FixedThreadPool()SingleThreadExecutor() 使用了这个队列
SynchronousQueue:不存储元素的阻塞队列
每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态
吞吐量通常要高于 LinkedBlockingQueue
CachedThreadPool使用了这个队列
PriorityBlockingQueue:具有优先级的、无限阻塞队列
DelayedWorkQueue:用于ScheduledThreadPool的添加执行任务,按周期或者延迟执行
threadFactory:每个线程创建的地方 ,可以给线程起个好听的名字,设置个优先级啥的
handler:拒绝策略
CallerRunsPolicy:只要线程池没关闭,就直接用调用者所在线程来运行任务
AbortPolicy:直接抛出 RejectedExecutionException 异常
DiscardPolicy:悄悄把任务放生,不做了
DiscardOldestPolicy:把队列里待最久的那个任务扔了,然后再调用 execute() 试试看能行不
也可以实现自己的 RejectedExecutionHandler 接口自定义饱和策略
三 线程池分析
FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
FixedThreadPool 的核心线程数和最大线程数都是指定值,也就是说当线程池中的线程数超过核心线程数后,任务都会被放到阻塞队列中。
而这里选用的阻塞队列是 LinkedBlockingQueue,使用的是默认容量 Integer.MAX_VALUE,相当于没有上限。
流程
线程数少于核心线程数,也就是设置的线程数时,新建线程执行任务
线程数等于核心线程数后,将任务加入阻塞队列
由于队列容量非常大,可以一直加加加
执行完任务的线程反复去队列中取任务执行
FixedThreadPool 用于负载比较重的服务器,为了资源的合理利用,需要限制当前线程数量
SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
从参数可以看出来,SingleThreadExecutor 相当于特殊的 FixedThreadPool,线程1.
流程
线程池中没有线程时,新建一个线程执行任务
有一个线程以后,将任务加入阻塞队列,不停加加加
唯一的这一个线程不停地去队列里取任务执行
SingleThreadExecutor 用于串行执行任务的场景,每个任务必须按顺序执行,不需要并发执行。
CachedThreadPool
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
CachedThreadPool 没有核心线程,非核心线程数无上限,也就是全部使用外包,但是每个外包空闲的时间只有 60 秒,超过后就会被回收。
CachedThreadPool 使用的队列是 SynchronousQueue,这个队列的作用就是传递任务,并不会保存。
因此当提交任务的速度大于处理任务的速度时,每次提交一个任务,就会创建一个线程。极端情况下会创建过多的线程,耗尽 CPU 和内存资源。
流程
没有核心线程,直接向 SynchronousQueue 中提交任务
如果有空闲线程,就去取出任务执行;如果没有空闲线程,就新建一个
执行完任务的线程有 60 秒生存时间,如果在这个时间内可以接到新任务,就可以继续活下去,否则就销毁
由于空闲 60 秒的线程会被终止,长时间保持空闲的 CachedThreadPool 不会占用任何资源。CachedThreadPool 用于并发执行大量短期的小任务,或者是负载较轻的服务器。
ScheduledThreadPool
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1, threadFactory));
}
ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor, 最多线程数为 Integer.MAX_VALUE ,使用 DelayedWorkQueue 作为任务队列。
ScheduledThreadPoolExecutor 添加任务和执行任务的机制与ThreadPoolExecutor 有所不同。
scheduleAtFixedRate() :按某种速率周期执行
scheduleWithFixedDelay():在某个延迟后执行
四 线程池的关闭
shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
Java Executors小结的更多相关文章
- Java中文编码小结
Java中文编码小结 1. 只有 字符到字节 或者 字节到字符 的转换才存在编码转码; 2. Java String 采用 UTF-16 编码方式存储所有字符.unicode体系采用唯一的码点表示唯一 ...
- Java序列化小结
title: Java序列化小结 date: 2017-05-06 20:07:59 tags: 序列化 categories: Java基础 --- Java序列化就是将一个对象转化成一串二进制表示 ...
- [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors
[Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...
- Java 基础--小结
Java 基础--小结 java基础 Java源程序(.java文件)——>java字节码文件(.class文件)——>由解释执行器(java.exe)将字节码文件加载到java虚拟机( ...
- Java Executors(线程池)
Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序 ...
- Java多线程小结
简述 Java是支持多线程编程的语言,线程相比于进程更加轻量级,线程共享相同的内存空间,但是拥有独立的栈.减少了进程建立.销毁的资源消耗.jdk1.5后对java的多线程编程提供了更完善的支持,使得j ...
- debian/ubuntu部署java应用小结
近期改的Java应用即将部署,为了强强联合,需要把Java应用部署到linux,我们选择了debian系列.小结一下部署的大致过程,如下: Ubuntu已经默认安装了OpenJDK,但还是比较倾向官方 ...
- 面试贴:java异常小结
java的异常处理在面试中通常是个敏感的话题,这里我从整体框架方面稍微作一下我的小结. java的异常都继承Throwable这个类,也就是都可以抛出来的异常,在这个祖先类下,又分为如下子类: 1.E ...
- 不要使用Java Executors 提供的默认线程池
线程池构造方法 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUni ...
随机推荐
- Input is not proper UTF-8, indicate encoding !错误处理
xml 中如果包含部分 ascii 控制字符(小数字)则 chrome会报告如下类型错我: This page contains the following errors: error on line ...
- 十天入门java教程 Day02
1,常量,变量的理解 常量,程序运行过程中,不能改变的,叫常量. 变量,程序运行过程中,改变的,叫变量. 2,变量的理解 变量,用来存储数据的,数据类型,存放哪种数据的种类. 变量的概念:程序运行期间 ...
- UWP&WP8.1 基础控件——Grid
Grid是一个面板控件 Grid是UWP和WPF,WP8.1中最重要的一个控件,相当相当重要. 他是一个面板控件,是用来添加其他控件 但是呢 用法确实简单的很. 大概就这个样子. 你用工具箱拖, ...
- Python3 中hashlib及uuid的用法
Python3 中hashlib及uuid的用法: 可以生成随机ID import uuid import hashlib import time def creat_uuid(): return s ...
- iframe相关操作
内容摘要 父级获取iframe中的元素 父级触发iframe中的函数 iframe触发父级元素绑定的事件 iframe触发父级函数方法 iframe触发父级元素的值 parent.html <! ...
- JavaScript之DOM HTML
前言 JavaScript这门语言在一定程度上让我们html之间耦合度降低了,为什么这样说呢?JavaScript语言一样可以可以随意写入html页面一些东西,比如:JavaScript的DOM可以改 ...
- 最优的cuda线程配置
1 每个SM上面失少要有192个激活线程,寄存器写后读的数据依赖才能被掩盖 2 将 寄存器 的bank冲突降到最低,应尽量使每个block含有的线程数是64的倍数 3 block的数量应设置得 ...
- SpringBoot浏览器直接访问html
在resources文件夹或与其并列的文件夹下建立public文件夹,在public文件夹下的html文件可以通过浏览器中输入文件+后缀名的方式直接访问的. 一.public文件夹,就相当于在ecl ...
- 搜索【洛谷P2845】 [USACO15DEC]Switching on the Lights 开关灯
P2845 [USACO15DEC]Switching on the Lights 开关灯 题目背景 来源:usaco-2015-dec Farm John 最近新建了一批巨大的牛棚.这些牛棚构成了一 ...
- 2019-5-1 maven学习笔记
一.maven的好处 同样的项目使用maven工程来实现,由于不需要导入很多jar包,源码很小 原理:根据坐标到项目的仓库里查找需要的依赖 二.安装步骤 1.到http://maven.apache. ...