并发编程:线程池ThreadPoolExecutor的理解

1:线程池是什么:

线程池是并发编程必须要掌握的知识,在计算资源有限的情况下,线程的创建和销毁需要一定的性能,

而线程池原理很简单,类似于操作系统中的缓冲区的概念,它的流程:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。

线程池的优点:

第一:降低资源消耗,通过重复利用自己创建的线程降低线程创建和销毁造成的消耗。

第二: 提高响应速度,当任务到达时,任务可以不需要等到线程创建就能立即执行。

第三: 提高线程的可管理性。​线程是稀缺资源,如果无限的创建,不仅会消耗资源,还会较低系统的稳定性,使用线程池可以进行统一分配,调优和监控。

2:ThreadPoolExecutor是什么

ThreadPoolExecutor是java.util.concurrent包下的线程池,继承ExecutorService类.

《阿里巴巴Java开发手册》中强制线程池不允许使用 Executors 去创建,而是通过 new ThreadPoolExecutor 实例的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

Executors 返回线程池对象的弊端如下:

FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致OOM。

CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。

3:线程池状态

线程池有五种状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。

1. RUNNING:线程池一旦被创建,就处于 RUNNING 状态,任务数为 0,能够接收新任务,对已排队的任务进行处理。

2:SHUTDOWN: 不会接收新任务,但会处理阻塞队列剩余任务

 3:STOP: 会中断正在执行的任务,并抛弃阻塞队列 任务

4:TIDYING: 任务全执行完毕,活动线程为 0 即将进入终结

5:TERMINATED: 终结状态

4:ThreadPoolExecutor的创建

1:构造方法

ThreadPoolExecutor的构造方法有多个,本文看构造参数最全的一个方法.

corePoolSize 核心线程数目 ( 最多保留的线程数 )
maximumPoolSize 最大线程数目 
keepAliveTime 生存时间 ( 针对救急线程)
unit 时间单位 - 针对救急线程
workQueue 阻塞队列
threadFactory 线程工厂 - 为线程创建时起的名字
handler 拒绝策略

2:线程创建的步骤:

线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行任务。

当线程数达到 corePoolSize 并没有线程空闲,这时再加入任务,新加的任务会被加入workQueue 队列排 队,直到有空闲的线程。

如果队列选择了有界队列,那么任务超过了队列大小时,会创建 maximumPoolSize - corePoolSize 数目的线 程来救急。

如果线程到达 maximumPoolSize 仍然有新任务这时会执行拒绝策略。

5:基于ThreadPoolExecutor实现的线程池

1:newFixedThreadPool 

  核心线程数 == 最大线程数(没有救急线程被创建),因此也无需超时时间
阻塞队列是无界的,可以放任意数量的任务   
  适用于任务量已知,相对耗时的任务

 2:newCachedThreadPool

核心线程数是 0, 最大线程数是 Integer.MAX_VALUE,救急线程的空闲生存时间是 60s,意味着 全部都是救急线程(60s 后可以回收), 救急线程可以无限创建 ,队列采用了 SynchronousQueue 实现特点是,它没有容量.

整个线程池表现为线程数会根据任务量不断增长,没有上限,当任务执行完毕,空闲 1分钟后释放线 程。 适合任务数比较密集,但每个任务执行时间较短的情况

3:newSingleThreadExecutor

多个任务排队执行。线程数固定为 1 ,任务数多于 1 时,会放入无界队列排队。任务执行完毕,这唯一的线程 也不会被释放。

 6:关闭线程池

1:shutdown 

线程池状态变为 SHUTDOWN
不会接收新任务
但已提交任务会执行完
此方法不会阻塞调用线程的执行

 2:shutdownNow

线程池状态变为 STOP
不会接收新任务
会将队列中的任务返回
并用 interrupt 的方式中断正在执行的任务

3:其他方法:

不在 RUNNING 状态的线程池,此方法就返回 true
boolean isShutdown();


线程池状态是否是 TERMINATED
boolean isTerminated();


调用 shutdown 后,由于调用线程并不会等待所有任务运行结束,因此如果它想在线程池 TERMINATED 后做些事情,可以利用此方法等待
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

    

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值