Java并发:一篇搞定线程池
2020-12-13 04:47
标签:eject 也会 repo maximum 管理 factory 作用 日志 来讲 原文地址:https://www.nowcoder.com/discuss/152050?type=0&order=0&pos=6&page=0 本文是在原文的基础+理解,想要系统学习,请看原文地址。 1.1 线程池的概念 线程池(thread pool): 一种线程使用模式。线程的创建销毁是十分消耗资源的(线程创建消耗内存、线程上下文切换从消耗CPU资源)。使用线程池可以更加充分的协调应用CPU、内存、网络、I/O等系统资源。在程序启动首先创建线程,在程序启动后可以将任务直接扔到线程池中,由线程池来执行这个任务。 1.2 线程池的解决的问题 ①线程创建销毁会开辟祸首虚拟机栈、本地方法栈和程序技术器等线程私有内存。 ②如不加控制,线程数量在达到一定值时,由于线程上下文切换需要互斥、通信,会造成CPU资源浪费,极端情况下,系统分配的时间片都用来完成上下文切换,而没有时间去执行真正的任务。 ③频繁的创建销毁线程增加并发编程的风险。 ④线程池可以解决线程过多时的等待或友好的决绝服务。 1.3 线程池作用 ①利用线程池管理复用线程,控制最大并发数。(避免由于先吃过多,造成完成上下文切换而真正任务不执行) ②实现任务线程队列缓存策略和拒绝机制。(优雅的处理线程过多情况) ③实现某些与实践相关的功能。(可以利用线程池完成定时任务) ④隔离线程环境。(可以将不同类型的线程池放到一台服务器,隔离不同服务,避免线程相互影响) 1.4 线程池的有点 ①降低资源消耗,避免频繁的内存申请和销毁 ②提高响应速度,不需要完成线程的创建,直接执行任务(前提是线程池中有空闲的线程) ③提高线程的可管理性,使用线程池可以同理管理、分配、调优和监控。 首先从ThreadPoolExecutor构造方法来讲自定义ThreadFactory和RejectedExecutionHandler,编写一个最简单的线程池。通过ThreadPoolExecutor的execute和addWorker两个核心方法。 参数说明: ①corePoolSize:表示核心线程数: corePoolSize=0,则任务执行完之后没有其他任务进入会销毁鲜线程池中的线程 corePoolSize>0,本地任务执行完毕后,线程池会保留corePoolSize个线程 ②maximumPoolSize:表示线程池能够容纳同时执行的最大线程数 maximumPoolSize>=1,如果线程池中的线程执行,则数量大于等于1. 如果需要执行的线程数大于maximumPoolSize个线程,需要第五个参数handler来处理,缓存还是 丢弃。 ③keepAliveTime:表示线程池中的线程空闲时间 当空闲时间达到keepAliveTime时,同时线程池中线程数大于信合线程数,则这个线程会被销毁。 利用这个参数,可以避免资源的浪费。 当allowCoreThreadTimeOut = true,核心线程超时也会被回收。 由源码可知,allowCoreThreadTimeOut是由volatile修饰,说明这个值变化对说有线程池中的线程可见,由于没有赋初值,默认值是false,表示核心线程超时不会被回收。 可以由方法设定,如果设置为true时,要保证线程空闲时间
④unit:表示时间单位 keepAliveTime的单位通常是TimeUnit.SECONDS. ⑤workQueue:表示缓存队列 当请求的线程数大于最大的线程并发数,线程会进入这个blockingQueue,阻塞保证出队入队的原子性 ⑥threadFactory:线程工厂 用来生产一组相同任务的线程。 线程池的命名是通过给这个factory增加组名前缀来实现的。 虚拟机栈在分析时知道线程任务是那个线程工厂生产的。 ⑦handler:表示拒绝策略的对象 当待执行的线程大于阻塞队列的最大值时,可以通过该策略处理请求,一种简单的限流保护,策略模式。 优雅的拒绝策略包括: 保存数据库进行消费填谷;在空闲的事再提取出来执行 转向某个提示页面 打印日志 2.1.1 corePoolSize 核心线程数量 线程池中应该报纸的线程数量,即使线程处于空闲期间,线程也会存在于线程池,除非设置allowCoreThreadTimeOut这个参数是false。当线程池中的线程数量少于核心线程数量,线程池会创建一个新的线程来执行这个任务,即使线程池存在空闲线程也会创建新线程。等线程池中的线程数量等于信心线程数量,这时不会再产生线程,任务会被放在队列中。 如果嗲用线程池的prestartAllCoreThreads(),线程池会提前创建并启动所有核心线程。 2.1.2 maximumPoolsize 线程池最大线程数,同时执行的线程 线程池允许创建的最大线程数 若队列满,并且已经创建的线程数小于最大线程数(固定线程数),则线程池会再创建新的线程放入到works中执行任务。无界队列参数没用。cachedThreadPool无效。 Java并发:一篇搞定线程池 标签:eject 也会 repo maximum 管理 factory 作用 日志 来讲 原文地址:https://www.cnblogs.com/dc-earl/p/11122370.html线程池介绍
线程池创建
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue
private volatile boolean allowCoreThreadTimeOut;
public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime )
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
allowCoreThreadTimeOut = value;
}
public int prestartAllCoreThreads() {
int n = 0;
while (addIfUnderCorePoolSize(null))
++n;
return n;
}
上一篇:百度地图API --地理位置定位