【多线程:线程池】ThreadPoolExecutor类的基本概念

简介: 【多线程:线程池】ThreadPoolExecutor类的基本概念

【多线程:线程池】ThreadPoolExecutor类的基本概念

01.介绍


ThreadPoolExecutor类实现了ExecutorService接口,他与ScheduledThreadPoolExecutor类的不同是ScheduledThreadPoolExecutor是带有任务调度功能的线程池实现 这个我们之后再讲。

02.ThreadPoolExecutor-池状态

ThreadPoolExecutor使用int的高3位来表示线程池状态,第29位表示线程数量

状态名 高3位 接收新任务 处理阻塞队列任务 说明
RUNNING 111 Y Y
SHUTDOWN 000 N Y 不会接收新任务,但会处理阻塞队列剩余任务
STOP 001 会中断正在执行的任务,并抛弃阻塞队列任务
TIDYING 010 任务全执行完毕,活动线程为0即将进入终结
TERMINAIED 011 终结状态

为什么线程池状态与线程池数量要用一个数字表示,而不用两个数字,原因是这两个信息存储在一个原子变量ctl中,这样以后就可以只用一次cas原子操作进行赋值。

03.构造方法


我们可以看到ThreadPoolExecutor类的构造方法有很多参数,我们一个一个解释
corePoolSize:核心线程数目
maximumPoolSize:最大线程数目
keepAliveTime:生存时间-针对急救线程
unit:时间单位-针对救急线程
workQueue:阻塞队列
threaFactory:线程工厂-可以为线程创建时起名
hander:拒绝策略

ThreadPoolExecutor与我们自定义线程池的区别

  1. 救急我们自定义线程池,线程池中只有一种线程就是核心线程,且我们的核心线程有take方法与pull方法。但ThreadPoolExecutor线程池有两种线程 一种是核心线程 数量时corePoolSize,一种是救急线程 数量是maximumPoolSize-corePoolSize,且核心线程只有take方法 救急线程只有pull方法,这就是为什么keepAlivTime与unit只针对救急线程。
  2. 自定义线程池不能规定线程池中线程的名字,ThreadPoolExecutor线程池则可以通过threaFactory参数改变线程的名字
  3. 自定义线程池与ThreadPoolExecutor线程池的拒绝策略

工作方式

介绍

我们知道自定义线程池中只有核心线程,所以自定义线程池的流程是
创建任务->交给空闲的核心线程执行->超出部分的任务放入任务队列->如果此时有空闲核心线程则从任务队列里获取任务执行->如果没有空闲线程 且任务队列也满了->生产线程执行拒绝策略
ThreadPoolExecutor线程池中有核心线程与救急线程,所以ThreadPoolExecutor线程池的流程是
补充:ThreadPoolExecutor线程池的核心线程没有超时时间,救急线程有。
创建任务->交给空闲核心线程执行->超出部分的任务放入任务队列->如果此时有空闲核心线程->如果此时有空闲核心线程则从任务队列里获取任务执行交给核心的->如果没有空闲线程 且任务队列也满了->创建救急线程 多出的任务交给救急线程执行->如果救急线程也没有空闲了->生产线程执行拒绝策略

解释

可以看出救急线程的作用是在核心线程与任务队列都满的情况下 创建救急线程 如果救急线程在超时时间内没有获取到任务则从线程池中移除。

拒绝策略

如果核心线程没有空闲 任务队列满了 救急线程没有空闲,在这种情况下执行拒绝策略,拒绝策略jdk提供了四种实现。

  1. AbortPolicy 让调用者抛出 RejectedExecutionException 异常,这是默认策略
  2. CallerRunsPolicy 让调用者运行任务
  3. DiscardPolicy 放弃本次任务
  4. DiscardOldestPolicy 放弃队列中最早的任务,本任务取而代之
目录
相关文章
|
11天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
34 1
|
1月前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
56 4
|
8天前
|
Java
【JavaEE】——多线程常用类
Callable的call方法,FutureTask类,ReentrantLock可重入锁和对比,Semaphore信号量(PV操作)CountDownLatch锁存器,
|
8天前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
8天前
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
2月前
|
Java
.如何根据 CPU 核心数设计线程池线程数量
IO 密集型:核心数*2 计算密集型: 核心数+1 为什么加 1?即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保 CPU 的时钟周期不会被浪费。
61 4
|
2月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
2月前
|
Java
线程池内部机制:线程的保活与回收策略
【10月更文挑战第24天】 线程池是现代并发编程中管理线程资源的一种高效机制。它不仅能够复用线程,减少创建和销毁线程的开销,还能有效控制并发线程的数量,提高系统资源的利用率。本文将深入探讨线程池中线程的保活和回收机制,帮助你更好地理解和使用线程池。
94 2
|
2月前
|
数据采集 Java Python
爬取小说资源的Python实践:从单线程到多线程的效率飞跃
本文介绍了一种使用Python从笔趣阁网站爬取小说内容的方法,并通过引入多线程技术大幅提高了下载效率。文章首先概述了环境准备,包括所需安装的库,然后详细描述了爬虫程序的设计与实现过程,包括发送HTTP请求、解析HTML文档、提取章节链接及多线程下载等步骤。最后,强调了性能优化的重要性,并提醒读者遵守相关法律法规。
69 0
|
3月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
62 1