为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第14天 线程池【治理线程的最大法宝】

标签:
Java

**课程名称:**玩转Java并发工具,精通JUC,成为并发多面手
**课程章节:**第3章 线程池【治理线程的最大法宝】
课程讲师: 悟空

课程内容

一、线程池介绍

软件中的”池“,可以理解为计划经济

1.1、如果不使用线程池,每个任务都新开一个线程处理

  • 一个线程简单
  • 线程比较多时,for循环创建线程
  • 当任务数量上升到1000

这样开销太大,对于Java语言来说,每一个Java中的线程都会直接对应到操作系统中的线程,在操作系统中创建1000个线程开销太大。 我们希望有固定数量的线程,来执行这1000个任务,这样就避免了反复创建线程并销毁线程所带来的开销问题。

操作系统能创建的线程数量是有上限的,用这种方法很有可能会超过上限,导致出错和OOM异常。

1.2、为什么要使用线程池

  • 反复创建线程开销大
  • 过多的线程会占用太多内存

解决以上两个问题的思路

  • 用少量的线程————避免内存占用过多
  • 让这部分线程都保持工作,且可以反复执行任务——避免生命周期的损耗

1.3、线程池的好处

  • 加快响应速度(不需要反复的创建和销毁,而且消除了线程创建带来的延迟之后,用户体验也是增强的,因为速度更快 了)
  • 合理利用CPU和内存(灵活地调整线程的数量,以便于线程不至于太多导致内存溢出,也不会太少浪费CPU和内存资源,以便达到一个平衡,达到效率最高点)
  • 统一管理,方便数据统计

1.4、线程池适合应用的场合

  • 服务器接收到大量请求时,使用线程池技术是非常合适的,它可以大大减少线程的创建和销毁次数,提高服务器的工作效率。Tomcat等服务器也是用线程池来实现的。
  • 实际上,在开发中,如果需要创建5个以上的线程,那么就可以使用线程池来管理。

2.1、线程池构造函数的参数。

参数名 类型 含义
corePoolSize int 核心线程数
maximumPoolSize int 最大线程数
keepAliveTime long 保持存活时间
workQueue BlockingQueue 任务存储队列
threadFactory ThreadFactory 当线程池需要新的线程的时候,会使用threadFactory来生成新的线程
Handler RejectedExecutionHandler 由于线程池无法接收你所提交的任务的拒绝策略
  • corePoolSize指的是核心线程数:线程池在完成初始化后,默认情况下,线程池中并没有任何线程,线程池会等待任务到来时,再创建新线程去执行任务。
  • 线程池有可能会在核心线程数的基础上,额外增加一些线程,但是这些新增加的线程数有一个上限,这就是最大线程数maxPoolSize
    图片描述

2.1.1、添加线程规则

  1. 如果线程数小于corePoolSize,即使其它线程处于空闲状态,也会创建一个新线程来运行新任务。(只要有任务提交进来,就创建新线程)
  2. 如果线程数等于(或大于)corePoolSize但少于maximumPoolSize,则将任务放入队列。
  3. 如果队列已满,并且线程数小于maxPoolSize,则创建一个新线程来运行任务。
  4. 如果队列已满,并且线程数大于或等于maxPoolSize,则拒绝该任务。
    图片描述

2.1.2、是否需要增加线程的判断顺序是

  • corePoolSize
  • workQueue
  • maxPoolSize

maxPoolSize满了则拒绝

2.1.3、举个例子

  • 线程池:核心池大小为5,最大池大小为10,队列为100。
  • 因为线程中的请求最多会创建5个,然后任务将被添加到队列中,直到达到100。当队列已满时,将创建最新的线程maxPoolSize,最多到10个线程,如果再来任务,就拒绝。

2.1.4、增减线程的特点

  1. 通过设置corePoolSize和maxPoolSize相同,就可以创建固定大小的线程池。
  2. 线程池希望保持较少的线程数,并且只有在负载变得很大时才增加它。
  3. 通过设置maximumPoolSize为很高的值,例如Integer.MAX_VALUE,可以允许线程池容纳任意数量的并发任务。
  4. 是只有队列满时才创建多于corePoolSize的线程,所以如果你使用的是无界队列(例如LinkedBlockingQueue),那么线程数就不会超过corePoolSize。

2.1.5、keepAliveTime

  • 如果线程池当前线程数多于corePoolSize,那么如果多余的线程空闲时间超过keepAlive,它们就会被终止。核心数量不会被回收 ,除非设置了allowCoreThreadTimeOut(true)
    ,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭,通常不采用这样的方式

学习收获

今天学习了线程池的相关知识,并进行了实际操作,收获巨大!
图片描述

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
6
获赞与收藏
11

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消