线程池
本文最后更新于55 天前,其中的信息可能已经过时。
线程池

线程池

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我

线程池好处:

  1. 降低资源的消耗。 (减少了线程的创建和销毁所需时间,线程的创建是消耗内存的
  2. 提高响应的速度 。任务可以不需要等到线程创建就能立即执行。
  3. 方便管理。 线程池可以进行统一的分配,调优和监控。

三大方法

  1. 单一线程 (只能有一个线程在执行)

    创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

  2. 固定线程(设置最大可执行的线程数)

    创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

  3. 可伸缩线程(可多可少,根据电脑配置)

    创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

七个参数

  • corePoolSize(必需): 核心线程数。即池中一直保持存活的线程数,即使这些线程处于空闲。但是将allowCoreThreadTimeOut参数设置为true后,核心线程处于空闲一段时间以上,也会被回收。
  • maximumPoolSize(必需): 池中允许的最大线程数。当核心线程全部繁忙且任务队列打满之后,线程池会临时追加线程,直到总线程数达到maximumPoolSize这个上限。
  • keepAliveTime(必需): 线程空闲超时时间。当非核心线程处于空闲状态的时间超过这个时间后,该线程将被回收。将allowCoreThreadTimeOut参数设置为true后,核心线程也会被回收。
  • unit(必需): keepAliveTime参数的时间单位。有:TimeUnit.DAYS(天)、TimeUnit.HOURS(小时)、TimeUnit.MINUTES(分钟)、TimeUnit.SECONDS(秒)、TimeUnit.MILLISECONDS(毫秒)、TimeUnit.MICROSECONDS(微秒)、TimeUnit.NANOSECONDS(纳秒)
  • workQueue(必需): 任务队列,采用阻塞队列实现。当核心线程全部繁忙时,后续由execute方法提交的Runnable将存放在任务队列中,等待被线程处理。
  • threadFactory(可选): 线程工厂。指定线程池创建线程的方式。
  • handler(可选): 拒绝策略。当线程池中线程数达到maximumPoolSize且workQueue打满时,后续提交的任务将被拒绝,handler可以指定用什么方式拒绝任务。

 

线程池优化了解吗(40%可能性被问到)

 

  • 用ThreadPoolExecutor自定义线程池,看线程是的用途,如果任务量不大,可以用无界队列,如果任务量非常大,要用有界队列,防止OOM
  • 如果任务量很大,还要求每个任务都处理成功,要对提交的任务进行阻塞提交,重写拒绝机制,改为阻塞提交。保证不抛弃一个任务
  • 最大线程数一般设为2N+1最好,N是CPU核数
  • 核心线程数,看应用,如果是任务,一天跑一次,设置为0,合适,因为跑完就停掉了,如果是常用线程池,看任务量,是保留一个核心还是几个核心线程数
  • 如果要获取任务执行结果,用CompletionService,但是注意,获取任务的结果的要重新开一个线程获取,如果在主线程获取,就要等任务都提交后才获取,就会阻塞大量任务结果,队列过大OOM,所以最好异步开个线程获取结果。
有几种常见的线程池
  • 定长线程池 只有核心线程,线程数量固定,执行完立即回收,队列为链表结构的有界队列。
  • 定时线程池 核心线程池固定,非核心线程池数量无线,执行完闲置10ms后回收,队列为延时阻塞队列
  • 可缓存线程池 无核心线程池,非核心线程池数量无线,执行完闲置60ms后回收,任务队列为不存储元素的阻塞队列
  • 单线程池化线程池 只有一个核心线程,无非核心线程,执行完立即回收,任务队列为链表结构的有界队列

 

怎么确定核心线程数

  • 需要根据业务来实际判断,没有一个标准万一的答案,

    • 如果是个IO密集型的任务呢,线程执行到一半到了IO的阶段了,而IO的速度远不及CPU,这时与其让线程光等着,不如多创几条线程去干别的事,一般是 2*cpu核心数 +1 +2这样
    • 如果是个CPU密集型任务呢,我们不能创建太多条线程,因为太多线程反而会增大线程切换的开销,而且会增大线程间增夺资源的可能。不如少创几条线程有条不紊的执行任务,一般是cup核心数+1。
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇