A100_线程池

内容介绍

1.线程池

1.线程池

在这里插入图片描述

1.1为什么用线程池?

1 线程并发数量过多,抢占系统资源从而导致阻塞。(控制并发数量)

2 .创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率和速度。(线程复用)
3.对线程进行一些简单的管理。(管理线程的生命周期)

1.2 线程池原理-重点

核心线程 等待队列 非核心线程 拒绝策略
如果有空闲的线程直接使用,没有空闲的线程并且线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务
线程数量达到了corePoolSize,则将任务移入队列等待空闲线程将其取出去执行(通过getTask()方法从阻塞队列中获取等待的任务,如果队列中没有任务,getTask方法会被阻塞并挂起,不会占用cpu资源,整个getTask操作在自旋下完成)
队列已满,新建线程(非核心线程)执行任务,空闲下来以后,非核心线程会按照时间策略进行销毁
队列已满,总线程数又达到了maximumPoolSize,就会执行任务拒绝策略。

handler:表示当拒绝处理任务时的策略(①AbortPolicy丢弃任务并抛出RejectedExecution异常;②DiscardPolicy丢弃任务,但是不抛出异常;③DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务;④CallerRunsPolicy由调用线程处理该任务)
在这里插入图片描述

1.3常见四种线程池

Jdk官方提供了常见四个静态方法来创建常用的四种线程.
CachedThreadPool:可缓存
FixedThreadPool :固定长度
SingleThreadPool:单个
ScheduledThreadPool:可调度

Excutors这个工具类中,util是工具类,以后见到以s结尾也是工具类.

Collections Arrays Paths等

(1)CachedThreadPool() 可缓存线程池-可以无限制创建

在这里插入图片描述

根据源码可以看出:
这种线程池内部没有核心线程,线程的数量是有限制的 最大是Integer最大值。
在创建任务时,若有空闲的线程时则复用空闲的线程,若没有则新建线程。
没有工作的线程(闲置状态)在超过了60S还不做事,就会销毁。
适用:执行很多短期异步的小程序或者负载较轻的服务器。

(2)FixedThreadPool 定长线程池

在这里插入图片描述

根据源码可以看出:
该线程池的最大线程数等于核心线程数,所以在默认情况下,该线程池的线程不会因为闲置状态超时而被销毁。
如果当前线程数小于核心线程数,并且也有闲置线程的时候提交了任务,这时也不会去复用之前的闲置线程,会创建新的线程去执行任务。如果当前执行任务数大于了核心线程数,大于的部分就会进入队列等待。等着有闲置的线程来执行这个任务。
适用:执行长期的任务,性能好很多。

(3)SingleThreadPool

在这里插入图片描述

根据源码可以看出:
有且仅有一个工作线程执行任务
所有任务按照指定顺序执行,即遵循队列的入队出队规则。
适用:一个任务一个任务执行的场景。

(4)ScheduledThreadPool

在这里插入图片描述

根据源码可以看出:
DEFAULT_KEEPALIVE_MILLIS就是默认10L,这里就是10秒。这个线程池有点像是CachedThreadPool和FixedThreadPool 结合了一下。
不仅设置了核心线程数,最大线程数也是Integer.MAX_VALUE。
这个线程池是上述4个中唯一一个有延迟执行和周期执行任务的线程池。
适用:周期性执行任务的场景(定期的同步数据)
总结:除了new ScheduledThreadPool 的内部实现特殊一点之外,其它线程池内部都是基于ThreadPoolExecutor类(Executor的子类)实现的。

(5)ThreadPoolExecutor类构造器语法形式:

ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,timeUnit,workQueue,threadFactory,handle);
方法参数:
corePoolSize:核心线程数(最小存活的工作线程数量)
maxPoolSize:最大线程数
keepAliveTime:线程存活时间(在corePoreSize<maxPoolSize情况下有用,线程的空闲时间超过了keepAliveTime就会销毁)
timeUnit:存活时间的时间单位
workQueue:阻塞队列,用来保存等待被执行的任务(①synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务;②LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;③ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小)
threadFactory:线程工厂,主要用来创建线程;
handler:表示当拒绝处理任务时的策略(①AbortPolicy丢弃任务并抛出RejectedExecutionException异常;②DiscardPolicy丢弃任务,但是不抛出异常;③DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务;④CallerRunsPolicy由调用线程处理该任务)

(6)在ThreadPoolExecutor类中几个重要的方法
  • execute()方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提交一个任务,交由线程池去执行。
  • submit()方法是在ExecutorService中声明的方法,在AbstractExecutorService就已经有了具体的实现,在ThreadPoolExecutor中并没有对其进行重写,这个方法也是用来向线程池提交任务的,实际上它还是调用的execute()方法,只不过它利用了Future来获取任务执行结果。
  • shutdown()不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务。
  • shutdownNow()立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。
  • isTerminated()方法
    调用ExecutorService.shutdown方法的时候,线程池不再接收任何新任务,但此时线程池并不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。在调用shutdown方法后我们可以在一个死循环里面用isTerminated方法判断是否线程池中的所有线程已经执行完毕,如果子线程都结束了,我们就可以做关闭流等后续操作了。
1.4 线程池中的最大线程数

一般说来,线程池的大小经验值应该这样设置:(其中N为CPU的核数)

如果是CPU密集型应用,则线程池大小设置为N+1
如果是IO密集型应用,则线程池大小设置为2N+1 322+1=65 642+1=129
如果一台服务器上只部署这一个应用并且只有这一个线程池,那么这种估算或许合理,具体还需自行测试验证。
但是,IO优化中,这样的估算公式可能更适合:
最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
因为很显然,线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。
创建线程的个数是还要考虑 内存资源是否足够装下相当的线程
下面举个例子:
比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。

3 课程总结

3.1 重点

1.线程池原理 *****
2.线程池可以自定义,并且通过Excutors提供四个常用线程池
3.为什么要调优-项目上线设置变好,可用变大。程序在运行过程中出现问题。 *****
4.通过java虚拟机参数的方式告诉jvm要使用多少内存,使用哪种垃圾回收器。 *****
5.jvm组成 *****
6.Jvm内存溢出 堆溢出 栈溢出 栈空间不足 *****
7.判断对象已死 可达性分析 *****
8.垃圾回收算法 分代回收:新生代(复制) 老年代(其他两种中一种) *****
9.常用垃圾回收器
在这里插入图片描述
10.怎么设置
开发环境 elipse.ini idea64.exe.vmoptions
在这里插入图片描述
上线:
外置tomcat catlina.bat/catlina.sh
Springboot java -jar 参数 xxx.jar

3.2 难点

11.Jvm分区
12.Jvm如何进行优化

3.3 如何掌握?

13.理解记忆
14.多结合代码

3.4 排错技巧(技巧)

15…
16…

4 课后练习

5 面试题

是否进行过jvm调优
线程池有何意义

6 扩展知识或课外阅读推荐(可选)

6.1 扩展知识
6.2 课外阅读
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值