JUC之线程池-三大方法-七大参数-四种拒绝策略
线程池:重点 三大方法 七大参数 四种拒绝策略
使用池化技术的理由:
我们的程序伴随着创建销毁线程十分浪费资源,
所以使用线程池,先创建线程,随用随取,用完归还
简单来说就是节约了资源。
使用线程池的好处:节省资源(最大并发线程数可控);提高了响应速度;方便管理
三大方法:
1.newFixedThreadPool(线程数):创建指定数量线程的线程池
2.newSingleThreadExecutor():创建单线程的线程池
3.newCacheThreadPool():随着请求的增多线程也随之创建,遇强则强
我们之前都是用Executors创建线程池的,但是到了后期强制不可以用
因此现在用ThreadPoolExecutor创建线程池
为什么不能使用Executors创建线程池呢?
1.FixedThreadPool和SingleThreadPool允许的请求队列的长度很大,约为21亿,
所以可能堆积大量的请求,导致oom
2.CachedThreadPool允许创建的线程数量很大,可能会导致创建大量的线程,从而导致oom
代码如下:
public static void main(String[] args) {
// 三大方法之一:创建指定的线程数
ExecutorService threadPool = Executors.newFixedThreadPool(5);
//三大方法之二:创建单个线程
//ExecutorService threadPool = Executors.newSingleThreadExecutor();
//三大方法之三:随之创建,遇强则强
//ExecutorService threadPool = Executors.newCachedThreadPool();
//使用线程池创建线程
try {
for (int i = 0; i < 100; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//使用完毕,关闭线程池
threadPool.shutdown();
}
}
七大参数:
1.corePoolSize: 核心线程数,一直存活,即使线程数小于核心线程数的时候,
线程数有空闲,线程池也会创建新的线程。
2.maximumPoolSize:最大线程数,当线程数大于核心线程数的时候并且任务队列已经满了的时候,
线程池会创建新的线程,当线程数大于最大线程数的时候并且任务队列已经满了,
会抛出异常。
3.keepAliveTime: 线程空闲时间:当线程的空闲时间达到keepAliveTime时,线程会退出,
直到线程数等于核心线程数,如果allowCoreThreadTimeout=true,
则会直到线程数为0。
4.TimeUnit unit 超时时间单位。
5.BlockingQueue<Runnable> workQueue:
阻塞队列,任务队列的容量。
6.ThreadFactory threadFactory:
线程工厂,基本不用设置。
7.RejectedExecutionHandler 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;
}
四种拒绝策略:
1.new ThreadPoolExecutor..AbortPolicy():线程池满了,还有线程想加入,不处理这个请求,跑出异常
2.new ThreadPoolExecutor.CallerRunsPolicy():如果任务被拒绝,则通过调用它线程执行此任务,哪来的回哪去
3.new ThreadPoolExecutor.DiscardPolicy():队列满了,丢掉任务,不会抛出异常
4.new ThreadPoolExecutor.DiscardOldestPolicy():队列满了,尝试去和最早的竞争,不会抛出异常
IO密集型,CPU密集型:(调优)
public static void main(String[] args) {
// 自定义线程池!工作 ThreadPoolExecutor
// 最大线程到底该如何定义
// 1、CPU 密集型,几核,就是几,可以保持CPu的效率最高!
// 2、IO 密集型 > 判断你程序中十分耗IO的线程,
// 程序 15个大型任务 io十分占用资源!
// 获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());
ExecutorService threadPool = new ThreadPoolExecutor(
2,
Runtime.getRuntime().availableProcessors(),
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy()); //队列满了,尝试去和
最早的竞争,也不会抛出异常!
try {
// 最大承载:Deque + max
// 超过 RejectedExecutionException
for (int i = 1; i <= 9; i++) {
// 使用了线程池之后,使用线程池来创建线程
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+" ok");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPool.shutdown();
}
}
JUC之线程池-三大方法-七大参数-四种拒绝策略的更多相关文章
- JUC 并发编程--08,线程池,三大方法,七大参数,4种拒绝策略,代码演示
三大方法: //线程池核心线程数为n, 最大线程数为 n ExecutorService fixedThreadPool = Executors.newFixedThreadPool(n); 源码: ...
- Java-五种线程池,四种拒绝策略,三种阻塞队列(转)
Java-五种线程池,四种拒绝策略,三种阻塞队列 三种阻塞队列: BlockingQueue<Runnable> workQueue = null; workQueue = n ...
- Java 线程池四种拒绝策略
jdk1.5版本新增了 JUC 并发包,其中一个包含线程池. 四种拒绝策略: 拒绝策略类型 说明 1 ThreadPoolExecutor.AbortPolicy 默认拒绝策略,拒绝任务并抛出任务 2 ...
- 线程池是什么?Java四种线程池的使用介绍
使用线程池的好处有很多,比如节省系统资源的开销,节省创建和销毁线程的时间等,当我们需要处理的任务较多时,就可以使用线程池,可能还有很多用户不知道Java线程池如何使用?下面小编给大家分享Java四种线 ...
- JUC之线程池基础
线程池 定义和方法 线程池的工作时控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等待其他线程执行完成,再从队列中取出任 ...
- JUC之线程池基础与简单源码分析
线程池 定义和方法 线程池的工作时控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等待其他线程执行完成,再从队列中取出任 ...
- 【转】JUC下面线程池介绍
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- Java创建线程池的方法
Executors创建四种线程池: CachedThreadPool:可缓存的线程池,该线程池中没有核心线程,非核心线程的数量为Integer.max_value,当有需要时创建线程来执行任务,没有需 ...
- 源码分析—ThreadPoolExecutor线程池三大问题及改进方案
前言 在一次聚会中,我和一个腾讯大佬聊起了池化技术,提及到java的线程池实现问题,我说这个我懂啊,然后巴拉巴拉说了一大堆,然后腾讯大佬问我说,那你知道线程池有什么缺陷吗?我顿时哑口无言,甘拜下风,所 ...
随机推荐
- 关于Mybaits
mybatis 返回多表多字段用 mybatis 返回多表多字段用 resultType=”java.util.Map”轻松解决问题.不用加什么DTO.这样前端要什么字段就返回什么字段.不用在对多余的 ...
- input输入框 只能输入数字 oninput = "value=value.replace(/[^\d]/g,'')" input输入框输入大于0的数字 oninput="value=value.replace(/\D|^0/g,'')"
项目中因为利用 element-ui 和avue两个ui框架搭建的 1.利用element-ui自带的校验需要注意点 prop :rules ref这三个属性 2.利用oninput时间进行校验 ...
- 一文了解Zookeeper
Zookeeper是Apache开源的一个分布式框架,它主要为分布式应用提供协调服务. Zookeeper主要负责存储和管理大家都关心的数据,一旦这些数据的状态发生变化,Zookeeper就会通知那些 ...
- 【Python】使用Python解释器
使用Python解释器 调用解释器 python -c command [arg] - 其中 command 要换成想执行的指令,就像命令行的 -c 选项. Python 模块也可以作为脚本使用 py ...
- Java知识系统回顾整理01基础05控制流程02 switch
一.switch switch 语句相当于 if else的另一种表达方式 switch可以使用byte,short,int,char,String,enum 注: 每个表达式结束,都应该有一个bre ...
- MATLAB鼠标事件
来源:https://blog.csdn.net/weixin_39090239/article/details/80586930 前记: 人机交互的方式--键盘开关.鼠标.触摸屏.体感传感器(Kin ...
- 跟我一起学Redis之五种基本类型及其应用场景举例(干了6个小时)
前言 来啦,老弟?来啦,上一篇就当唠唠嗑,接下来就开始进行实操撸命令,计划是先整体单纯说说Redis的各种用法和应用,最后再结合代码归纳总结. Redis默认有16个数据库(编号为0~15),默认使用 ...
- Linux系统的一些问题
1.操作系统提供的服务: - 进程调度 - 内存管理 - 磁盘管理 - 网络服务 - 设备管理 - 提供应用程序编程接口 2.shell是什么? shell是一种具有特殊用途的程序,主要用于读取用户输 ...
- 关于.netMVC 出现@ViewBag 出现错误(波浪红线)的解决方法
解决vs2015.vs2013解决mvc5 viewbag问题 1.关闭vs2015或者vs2013 打开我的电脑或者文件夹 2.打开我的电脑 在地址栏输入 %UserProfile%\AppData ...
- 【最短路】CF 938D Buy a Ticket
题目大意 流行乐队"Flayer"将在\(n\)个城市开演唱会,这\(n\)个城市的人都想去听演唱会,每个城市的票价不同,于是这些人就想是否能去其他城市听演唱会更便宜,但是去其他的 ...