JDK 线程池
JDK 线程池
线程池参数
在JDK的4种线程池之前, 先介绍一下线程池的几个参数
- corePoolSize 线程池的核心线程数量,
- maximumPoolSize 线程池的最大线程数量
- keepAliveTime 线程被回收的最大空闲时间
- keepAliveTime 的单位(ms、s、...)
- BlockingQueue 任务队列,存放任务
- ThreadFactory 线程工厂
- RejectedExecutionHandler 线程池拒绝策略(当任务过多的时候,线程池拒绝任务的方式)
allowCoreThreadTimeOut 允许核心线程池被回收, 默认 false, so 默认情况下 核心线程并不会被回收掉.
JDK 提供的四种线程池介绍
newFixedThreadPool
固定线程池数量, 核心线程数 = 最大线程数
任务队列: LinkedBlockingQueue(Integer.MAX_VALUE) 无界队列
适用于同时处理固定任务数的场景.
public static ExecutorService newFixedThreadPool(int nThreads) {
// coreThreads = maxThreads
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newCachedThreadPool
核心线程数为0, 最大为 Integer.MAX_VALUE,也就是当任务足够多的时候, 可以无限增加线程.
任务队列: SynchronousQueue 默认传入参数 fair=false
, 即处理任务非公平.
适用于处理小任务
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
SynchronousQueue
public SynchronousQueue(boolean fair) {
// fair = true 则会按照FIFO先入先出的顺序执行
// fair = false 则优先取出最新添加的任务, 如果任务多的话,最先添加的任务反而执行不到
transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}
newSingleThreadExecutor
单个线程的线程池
任务队列: LinkedBlockingQueue 同样是无界队列
适用于需要将任务按顺序执行的时候
public static ExecutorService newSingleThreadExecutor() {
// 核心线程数=最大线程数=1
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newScheduledThreadPool
固定核心线程数, 线程数量不会再增长, maximumPoolSize 这个参数对定时线程池没有作用.
任务队列: DelayedWorkQueue 无界队列, 这是 ScheduledThreadPoolExecutor 的一个内部类
适用于有延时 或者定时需求的场景
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
线程拒绝策略
AbortPolicy
拒绝新任务,并且抛出异常, 默认的拒绝策略
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 直接抛出异常
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
CallerRunsPolicy
当拒绝任务的时候,由调用线程处理该任务.
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 如果线程池未停止
if (!e.isShutdown()) {
// 当前线程直接调用任务的run方法
r.run();
}
}
}
DiscardPolicy
拒绝新任务,静悄悄的将新任务丢弃,而不通知(太坑了吧), 具体看它的代码也是什么事情都没做, 还真的就直接丢弃任务了.
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 任务被拒绝后,啥事情都不干
}
}
DiscardOldestPolicy
当任务满时, 抛弃旧的未处理的任务, 然后重新执行 execute 方法(此过程会重复), 除非 线程池 停止运行, 这种情况任务将被丢弃.具体看代码
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 如果线程池停止, 直接丢弃任务,不做任何处理
if (!e.isShutdown()) {
// 丢弃一个任务队列中的任务
e.getQueue().poll();
// 重新执行被拒绝的任务, 如果再次被拒绝, 则会一直重复这个过程
e.execute(r);
}
}
}
最后
这次的内容到这里就结束了,最后的最后,非常感谢你们能看到这里!!你们的阅读都是对作者的一次肯定!!!
觉得文章有帮助的看官顺手点个赞再走呗(终于暴露了我就是来骗赞的(◒。◒)),你们的每个赞对作者来说都非常重要(异常真实),都是对作者写作的一次肯定(double)!!!
JDK 线程池的更多相关文章
- jdk线程池主要原理
本文转自:http://blog.csdn.net/linchengzhi/article/details/7567397 正常创建一个线程的时候,我们是这样的:new thread(Runnable ...
- JDK线程池和Spring线程池的使用
JDK线程池和Spring线程池实例,异步调用,可以直接使用 (1)JDK线程池的使用,此处采用单例的方式提供,见示例: public class ThreadPoolUtil { private s ...
- 自己动手写线程池——向JDK线程池进发
自己动手写线程池--向JDK线程池进发 前言 在前面的文章自己动手写乞丐版线程池中,我们写了一个非常简单的线程池实现,这个只是一个非常简单的实现,在本篇文章当中我们将要实现一个和JDK内部实现的线程池 ...
- jdk线程池ThreadPoolExecutor工作原理解析(自己动手实现线程池)(一)
jdk线程池ThreadPoolExecutor工作原理解析(自己动手实现线程池)(一) 线程池介绍 在日常开发中经常会遇到需要使用其它线程将大量任务异步处理的场景(异步化以及提升系统的吞吐量),而在 ...
- JDK线程池的拒绝策略
关于新疆服务请求未带入来话原因的问题 经核查,该问题是由于立单接口内部没有成功调用接续的 “更新来电原因接口”导致的,接续测更新来电原因接口编码:NGCCT_UPDATESRFLAG_PUT ,立单接 ...
- JDK线程池的使用
转载自:https://my.oschina.net/hosee/blog/614319: 摘要: 本系列基于炼数成金课程,为了更好的学习,做了系列的记录. 本文主要介绍: 1. 线程池的基本使用 2 ...
- juc线程池原理(六):jdk线程池中的设计模式
一.jdk中默认线程池中的代理模式 单例类线程池只有一个线程,无边界队列,适合cpu密集的运算.jdk中创建线程池是通过Executors类中提供的静态的方法来创建的,其中的单例类线程池的方法如下: ...
- JDK线程池的实现
线程池 接口Executor 该接口只有一个方法,JDK解释如下 执行已提交的Runnable 任务的对象.此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节.调度等)分离开来的方 ...
- jdk线程池,使用手记
Executors----------------------------------------------Executors------------------------------------ ...
随机推荐
- rm, git rm, git rm --cached 区别与关系
HEAD, staging area, working copy在上篇<Git命令之回退篇 git revert git reset>已经讲过,不明白请自行传送过去. 1. rm 是仅仅删 ...
- java多线程编程(二)
1. wait 和 sleep 区别? 1.wait可以指定时间也可以不指定,sleep必须指定时间. 2.在同步中时,对cpu的执行权和锁的处理不同. wait:释放执行权,释放锁. sleep ...
- Python--列表简介
Python--列表简介 目录 Python--列表简介 一.列表 1. 访问列表元素 2. 索引从0而不是1开始 3. 使用列表中的各个值 二.修改.添加和删除元素 1. 修改列表元素 2. 在列表 ...
- vue中的钩子函数
什么是vue的钩子函数? Vue 实例在被创建时,会经过一系列的初始化过程,初始化过程中会运行一些函数,叫做生命周期钩子函数,通过运用钩子函数,用户在可以在Vue实例初始化的不同阶段添加自己的代码,以 ...
- Vue 组件库:Element
目录 Element 介绍 什么是 Element ? Element 快速入门 Element 常用组件 基础布局 容器布局 表单组件 表格组件 顶部导航栏组件 侧边导航栏组件 Element 介绍 ...
- 踩坑系列-Java Calendar
Calendar是Java util包下的日期Api,其中获取月份是当前月份-1 public class Demo { public static void main(String[] args) ...
- C# 实例解释面向对象编程中的开闭原则
在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...
- 手写RPC框架(六)整合Netty
手写RPC框架(六)整合Netty Netty简介: Netty是一个基于NIO的,提供异步,事件驱动的网络应用工具,具有高性能高可靠性等特点. 使用传统的Socket来进行网络通信,服务端每一个连接 ...
- JUC之Java中的阻塞队列及其实现原理
在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...
- 如何在TypeScript/JavaScript项目里引入MD5校验和
摘要:MD5校验和则是其中一种数学算法,通常是使用工具对文件计算得出的一组32 个字符的十六进制字母和数字. 本文分享自华为云社区<TypeScript/JavaScript项目里如何做MD5校 ...