线程池的相关知识点(三大方法,七大参数,四种拒绝策略)

一. 什么是线程池?

线程池就是以一个或多个线程[循环执行]多个应用逻辑的线程集合.

通俗解释就是事先准备好一些资源,有人要用,就来拿,用完还回!

二. 线程池的好处是什么?

1.降低资源的消耗,线程池中的线程是可以重用的,不用多次的创建和销毁,提高了系统的性能
2.提高响应速度
3.线程池中的队列可以管理大量的任务,任务的执行,调度,排队,丢弃等事宜都由线程池来管理,做到任务可控
4.方便管理,线程池对线程进行一些维护和管理,比如线程定时执行,线程生命周期管理,多少个线程并发,线程执行的监控等
线程复用,可以控制最大并发数,管理线

传统的编写线程:

1:新建线程,执行任务,任务完毕,线程销毁。线程的频繁新建/销毁都是由JVM管理的,非常的消耗系统性能。
2:当任务比较小时,花在创建和销毁线程上的时间会比任务执行的时间长。尤其是如果有大量的任务时,线程的大量创建和销毁,有内存溢出的风险。

三. 线程池介绍:

在这里插入图片描述
接口:
1.Executor 其内仅有execute(Runnable task);方法。
2.ExecutorService 继承Executor,对线程有更多的管理,常用的有:submit()方法、shutdown()方法等。
3.ScheduledExecutorService 继承ExecutorService,对线程又进一步的支持了定时执行的职能。

类:
1.AbstractExecutorService 默认实现了ExecutorService接口中的部分方法。
2.ThreadPoolExecutor 我们常用的类,里面的职能有:维护任务队列,维护线程组,管理线程调度,执行,监控,等。
3.ScheduledThreadPoolExecutor 里面的职能相对于父类ThreadPoolExecutor来说,多了对线程定时执行的职能。

三大方法:

//创建单个线程
ExecutorService executorService = Executors.newSingleThreadExecutor();
//创建固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
//创建可伸缩的,遇强则强,遇弱则弱
ExecutorService executorService = Executors.newCachedThreadPool();

线程池不允许用Executors去创建,而是通过ThreadPoolExecutor方式创建,理解线程池的参数和运行规则

Executors创建的弊端:
1).FixedThreadPool和SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE(约21亿),可能会堆积大量请求,导致OOM.
2).CachedThreadPool和ScheduledThreadPool:
允许创建线程数量为Integer.MAX_VALUE,可能会创建大量线程,导致OOM.

七大参数:

/**
* 线程池的构造函数
*/
 
public ThreadPoolExecutor(
//核心线程数    举例说明: 有编制的正式快递员员工个数
int corePoolSize,    
//最大线程数    双11了,包裹量急剧增多,正式员工忙不过来,只能新招临时工 =( 最大 - 核心 )      
int maximumPoolSize,   
 //临时工呆多久   临时工就是临时工(包裹量不多的时候会被辞退的),能呆几天    
long keepAliveTime,
 //临时工呆多久的计量单位  临时工呆多少小时,那么unit就计量单位为小时;临时工能呆多少天,unit计量单位就是天      
TimeUnit unit,  
//任务队列     需要派送的大量包裹存储的地方   
BlockingQueue<Runnable> workQueue,   
//线程工厂     
ThreadFactory threadFactory, 
//异常处理        
RejectedExecutionHandler handler)    

四种拒绝策略

  • AbortPolicy
    默认策略,不执行此任务,而且直接抛出RuntimeException。 切记execute()需要try catch,否则程序会直接退出

  • DiscardPolicy
    直接抛弃,任务不执行,空方法

  • DiscardOldestPolicy
    从队列里面抛弃head的一个任务,并再次尝试调用execute(task);

  • CallerRunsPolicy
    当前线程调用的execute(task)方法,当前线程阻塞在这里,直至task执行完毕

  • 自定义策略 (常用)自定义类实现RejectedExecutionHandler。例:可以先把任务写入文件或者数据库,以防止任务丢弃

线程池工作原理的流程图:
在这里插入图片描述

线程池工作原理描述:

1:有新任务了,尽可能的让核心线程去执行;
2:核心线程都在忙了,再来的任务就放到队列中去排队等待被执行;
3:队列中都塞满了任务,还来新任务,就临时招募非核心线程来执行刚到的新任务;
4:队列满了,核心线程/非核心线程都在忙,还来新任务,启用安全策略;
5:安全策略来处理仍源源不断到来的新任务,安全策略决定是丢弃新来的任务,还是其它处理。

四. 模拟线程池工作流程

在这里插入图片描述

1.Core核心线程有三个(1,2,3),已满
2.现加入3个人,没有空闲线程,则先进入等待区(阻塞队列)等待.
3.又来了3个人,没有空闲线程,等待区(阻塞队列也满),则创建新的线程(总线程数<max)来处理
4.现在max最大,阻塞队列也满了,接下来加入的人就会被拒绝!(四种拒绝策略)

  • (1) new ThreadPoolExecutor.AbortPolicy() //默认策略
    , 银行满了,还有人加入,不处理这个人并抛出异常 RejectExecutionException
  • (2)new ThreadPoolExecutor.CallerRunPolicy()
    //哪来的回哪去 会交给主线程处理
  • (3)new ThreadPoolExecutor.DiscardPolicy()
    //队列满了,丢掉任务,不抛出异常
  • (4)new ThreadPoolExecutor.DiscardOldestPolicy()
    //队列满了,会尝试和最早的竞争(若1号处理完了,则加入),不会抛出异常
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值