(一)并发编程之线程池

线程池是什么?为什么要使用线程池?

线程池用来管理和控制线程数量。
线程是种昂贵的资源,线程的创建、启动、销毁、调度都是需要额外的开销的。
线程池的优势:

  • 线程的复用。
  • 线程的管理。
  • 线程数量的控制。

第一:降低资源消耗.通过重复利用自己创建的线程降低线程创建和销毁造成的消耗.
第二: 提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行.
第三: 提高线程的可管理性.线程是稀缺资源,如果无限的创建,不仅会消耗资源,还会较低系统的稳定性,使用线程池可以进行统一分配,调优和监控。

java的框架实现:
在这里插入图片描述
Executors顾名思义,和Collections相似,是一个工具类。
Executor框架的最顶层实现是ThreadPoolExecutor类,Executors工厂类中提供的newScheduledThreadPool、newFixedThreadPool、newCachedThreadPool方法其实也只是ThreadPoolExecutor的构造函数参数不同而已。通过传入不同的参数,就可以构造出适用于不同应用场景下的线程池。
在这里插入图片描述
Executors使用有风险,不建议使用。
在这里插入图片描述

线程池的七个参数

在这里插入图片描述
我们来看看这几个参数的含义:

  1. corePoolSize: 线程池中的常驻核心线程数。
    (1)在创建了线程池后,当有请求任务来之后,就会安排池中的线程去执行请求任务,近似理解为今日当值线程
    (2)当线程池中的线程数目达到corePoolSize后,就会把到达的任务放入到缓存队列当中.

  2. maximumPoolSize: 线程池能够容纳同时执行的最大线程数,此值大于等于1

  3. keepAliveTime: 多余的空闲线程存活时间,当空间时间达到keepAliveTime
    值时,多余的线程会被销毁直到只剩下corePoolSize 个线程为止。
    (1)默认情况下:只有当线程池中的线程数大于corePoolSize时keepAliveTime才会起作用,直到线程中的线程数不大于corepoolSIze。

  4. unit:keepAliveTime的单位。

  5. workQueue:任务队列,被提交但尚未被执行的任务。

  6. threadFactory:表示生成线程池中工作线程的线程工厂,用户创建新线程,自定义线程名字。

  7. handler:拒绝策略,表示当线程队列满了并且工作线程大于等于线程池的最大显示 数(maxnumPoolSize)时如何来拒绝。
    (1) 有四种拒绝策略:
    ①AbortPolicy 直接抛出异常(默认
    ②DiscardPolicy丢弃当前被拒绝的任务,不抛出异常。(运行丢失的情况可以考虑
    ③CallerRunPolicy:"调用者运行"一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是该任务被线程池拒绝,由调用execute方法的线程执行该任务。
    ④DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交。
    在这里插入图片描述

线程池的状态

线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated
在这里插入图片描述
在这里插入图片描述
RUNNING

(1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。
(2) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

2、 SHUTDOWN

(1) 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。
(2) 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。

3、STOP

(1) 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
(2) 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

4、TIDYING

(1) 状态说明:当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。
(2) 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

5、 TERMINATED

(1) 状态说明:线程池彻底终止,就变成TERMINATED状态。
(2) 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

线程池底层的工作原理

在这里插入图片描述
线程的顺序不能乱,是核心线程–>队列–>最大线程–>拒绝策略。
这里有几个个小问题:

  1. 如果是Executors创建的FixedThreadPool、CachedThreadPool(队列长度为Integer.MAX_VALUE)顺序会改变吗?
  2. 程序刚刚启动核心线程会被创建吗?

后面的博客给答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值