线程池也就那么一回事嘛!

线程池详讲

  • 一、线程池的概述
  • 二、线程池
  • 三、自定义线程池
  • 四、线程池工作流程图
  • 五、线程池应用场景

一、线程池的概述

线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们所知的实现了 Runnable 或 Callable 接口的实例对象。

线程池的优势:

  1. 线程和任务分离,提升了线程重用性。
  2. 控制线程的并发数量,降低服务器压力,统一管理所有线程。
  3. 提升系统响应速度,假如创建线程用的时间为 T1,执行任务用的时间为 T2,销毁线程用的时间为 T3,那么使用线程池就免去了 T1 和 T3 的时间。

二、线程池

为什么要使用线程池?

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

jdk 自带的四种线程池

Java 通过 Executors 提供了四种线程池,分别是:

  • newCachedThreadPool 创建一个可缓存线程池,如果线程池长度不超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超过的线程会在队列中等待。
  • newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。

通过 Executors. 上面的静态方法得到的连接池都有一个共同点,就是他们都是去 new ThreadPoolExecutor 然后进行返回。

在这里插入图片描述

接下来对 ThreadPoolExecutor 构造方法的每个操作进行解释:

参数意义
corePoolSize指定了线程池里的线程数量,核心线程池大小(0-Integer.MAX_VALUE)
maximumPoolSize指定了线程池里的最大线程数量(0-Integer.MAX_VALUE)
keepAliveTime当线程池线程数量大于corePoolSize时候,多出来的空闲线程,多长时间会被销毁(0-Integer.MAX_VALUE)
unit时间单位,TimeUnit
workQueue任务队列(阻塞任务队列),用于存放提交但是尚未被执行的任务
threadFactory线程工厂,用于创建线程,线程工厂就是给我们new线程的
handler所谓拒绝策略,是指将任务添加到线程池中时,线程池拒绝该任务所采取的相应策略

常见的工作队列(对应参数5)我们有如下选择,这些阻塞队列,阻塞队列的意思是,当队列中没有值的时候,取值操作会阻塞,一直等队列中产生值。

  • ArrayBlockingQueue:基于数据结构的有界阻塞队列,FIFO。
  • LinkedBlockingQueue:基于链表结构的有界阻塞队列,FIFO。

线程池提供的四种拒绝策略(对应参数7)

  • AbortPolicy:直接抛出异常,默认策略
  • CallerRunsPolicy:用调用者所在线程来执行任务
  • DiscardOldestPolicy:丢弃阻塞队列中最靠前的任务,并执行当前任务。
  • DiscardPolicy:直接丢弃任务。

了解完 ThreadPoolExecutor 构造方法的各个参数之后,来看看 jdk 为我们提供的四个线程池是如何实现的吧:

  • newCachedThreadPool
    public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}
来看看其参数:
核心线程池大小为:0
最大线程数支持:Integer.MAX_VALUE
线程过期时间为60s
使用了 SynchronousQueue 作为工作队列。
拒绝策略没有指定,默认是抛出异常。
  • newFixedThreadPool
    public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}
来看看其参数:核心线程数和最大线程数需咱指定,都是相同的,也就是说不支持缓存线程。没有缓存线程,自然过期时间就是0了。工作队列使用的是 LinkedBlockingQueue拒绝策略没有指定,默认是抛出异常。
  • newScheduledThreadPool
public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());
}
核心线程池大小=传入参数
最大线程池大小为Integer.MAX_VALUE
线程过期时间为0ms
DelayedWorkQueue作为工作队列.
  • newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
核心线程池大小=1
最大线程池大小为1
线程过期时间为0ms
LinkedBlockingQueue作为工作队列.

三、自定义线程池

​ 这里是针对JDK1.8版本,使用JDK自带的线程池会出现OOM问题,中小型公司一般很难遇到,在阿里巴巴开发文档上面有明确的标识:

在这里插入图片描述
上面解释了 ThreadPoolExecutor 的构造参数,那现在自己自定义的话其实很简单,本质的话就是自定义 ThreadFactory(实现里面的 newThread 方法即可),如下所示:

    public static void main(String[] args) {AtomicInteger num = new AtomicInteger(0);ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,30,60L, TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),/*Executors.defaultThreadFactory()*/new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread thread = new Thread(r);thread.setName("myThread-" + num.getAndIncrement());thread.setDaemon(false);return thread;}},new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 100; i++) {threadPoolExecutor.submit(() -> {System.out.println(Thread.currentThread() + "-----------------");});}}

四、线程池工作流程图

在这里插入图片描述

五、线程池应用场景

  1. Tomcat 在处理 Web 请求的时候就用了线程池,我在《Tomcat架构解析》这边书看到的,下面给出书中Tomcat处理 Web 请求的流程图吧(手机不行,拍的不是很轻,感兴趣大家可以买来看看,不错的)。
    请添加图片描述Tomcat 使用的线程池是自定义的。

  2. 在开发通讯系统的时候,我是想用它出来消息的串行问题的,提高效率。

  3. 网购商品秒杀。

  4. 云盘文件上传和下载。

  5. 12306网上购票系统等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/106199.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拥塞控制(TCP限制窗口大小的机制)

拥塞控制机制可以使滑动窗口在保证可靠性的前提下&#xff0c;提高传输效率 关于滑动窗口的属性以及部分机制推荐看TCP中窗口和滑动窗口的含义以及流量控制 拥塞控制出现的原因 看了上面推荐的博客我们已经知道了&#xff0c;由于接收方接收数据的能力有限&#xff0c;所以要通…

暑期习题练习 C语言

编程能力小提升&#xff01; 前言一、转义字符二、重命名与宏定义三、三目运算符四、计算日期到天数转换五、计算字符串长度六、宏定义应用七、const常量八、C语言基础九、const常量&#xff08;二&#xff09;十、符号运算十一、记负均正十二、SWITCH&#xff0c;CASE十三、错…

Nexus 如何配置匿名用户访问一个仓库

现在有这样一个需求&#xff0c;我们需要匿名用户访问 Nexus 的一个公共仓库。 设置 Roles 在满足这个需求之前&#xff0c;我们需要设置一个 Roles。 Role 的名字是可以随填写的。 这里关键的问题在你需要访问的仓库的 View 的权限需要设置 Read 和 Browse 这 2 个权限。 如…

JDK1.8 安装教程(linux)

一、 检查当前系统是否已安装JDK 通过命令java –version 如果有出现如下图提示表示有安装&#xff0c;则无需再安装 二、 安装JDK 通过JDK官网https://www.oracle.com/上下载需要的JDK 版本&#xff0c;下载完成后上传到linux 系统上指定的文件夹下。&#xff08;可以用宝…

Springboot配置高级

临时属性设置 带属性数启动SpringBoot java –jar springboot.jar –-server.port80携带多个属性启动SpringBoot&#xff0c;属性间使用空格分隔 属性加载优先顺序 参看https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-fea…

Linux驱动开发(Day5)

思维导图&#xff1a; 不同设备号文件绑定&#xff1a;

Wireshark流量分析

目录 1.基本介绍 2.基本使用 1&#xff09;数据包筛选: 2&#xff09;筛选ip&#xff1a; 3&#xff09;数据包还原 4&#xff09;数据提取 3.wireshark实例 1.基本介绍 在CTF比赛中&#xff0c;对于流量包的分析取证是一种十分重要的题型。通常这类题目都是会提供一个包含…

移动,电信,联通流量卡该怎么选?

是电信便宜&#xff0c;移动稳定&#xff0c;还是联通性价比高&#xff1f; ​ 今天&#xff0c;小编从三大流量卡的优缺点方面来讲&#xff0c;教你如何选择流量卡了。 一、移动流量卡 优点&#xff1a;信号好&#xff0c;可以说走到什么地方都有信号。 缺点&#xff1a;资…

【面试题】JDK(工具包)、JRE(运行环境和基础库)、JVM(java虚拟机)之间的关系?

【面试题】JDK、JRE、JVM之间的关系&#xff1f; JDK(Java Development Kit):Java开发工具包&#xff0c;提供给Java程序员使用&#xff0c;包含了JRE&#xff0c;同时还包含了编译器javac与自带的调试工具Jconsole、jstack等。 JRE(Java Runtime Environment):Java运行时环境&…

Jvm之JIT优化详细解释

文章目录 一、JIT 产生的背景二、HotSpot虚拟机内置JIT编译器1. Client Compiler2. Server Compiler3. 查看本地编译器模式 三、常见热点探测技术1. 基于计数器的热点探测2. 基于采样的热点探测2.1 方法调用计数器2.2 回边计数器 四、常见JIT优化手段1. 公共子表达式消除2. 方法…

【android12-linux-5.1】【ST芯片】驱动与HAL移植后数据方向异常

ST的传感器驱动与HAL一直成功后&#xff0c;能拿到数据了&#xff0c;但是设备是横屏&#xff0c;系统默认是竖屏。就会出现屏幕自动转动时方向是错的的情况&#xff0c;设备横立展示的是竖屏&#xff0c;设备竖立展示的是横屏。 这个是PCB上设计的传感器贴片方向和横屏不一致…

windows10系统安装docker desktop超常见问题

问题报错&#xff1a; An unexpected error was encountered while executing a WSLcommand. Common causes include access rights issues, which occurafter waking the computer or not being connected to your domain/active directory. Please try shutting WSL down (w…

深度学习基础知识-pytorch数据基本操作

1.深度学习基础知识 1.1 数据操作 1.1.1 数据结构 机器学习和神经网络的主要数据结构&#xff0c;例如 0维&#xff1a;叫标量&#xff0c;代表一个类别&#xff0c;如1.0 1维&#xff1a;代表一个特征向量。如 [1.0&#xff0c;2,7&#xff0c;3.4] 2维&#xff1a;就是矩…

SAP 之如何定义功能范围Function Area

目录 目录 前言 一、注意点 二、使用步骤 1. Step by step 2. 其它功能 总结 前言 在SAP中&#xff0c;FA功能范围是一个组织单元&#xff0c;一般根据活动对产生的运营费用进行分类。例如生产、管理、销售、研发等&#xff0c;可以分配给成本中心Cctr、GL总账科目、Ord…

研磨设计模式day11观察者模式

目录 场景 代码示例 定义 观察者模式的优缺点 本质 何时选用 简单变型-区别对待观察者 场景 我是一家报社&#xff0c;每当我发布一个新的报纸时&#xff0c;所有订阅我家报社的读者都可以接收到 代码示例 报纸对象 package day11观察者模式;import java.util.Observ…

扫雷小游戏

目录 一.扫雷小游戏 二.游戏主体一览 ​编辑 三.模块化设计扫雷游戏 3.1打印欢迎菜单 3.2创建两个二维数组 3.3棋盘稍加修改 3.4布置雷 3.5排查雷 四.游戏总体代码 4.1game.h头文件 4.2game.c函数实现源文件 4.3游戏main函数主体 五.游戏效果图 一.扫雷小游戏 这是…

建设全球研发中心城市,长沙政协将会发挥怎样的作用?

政协力量&#xff0c;会如何推动一座城市的发展&#xff1f;在全国各大城市都力“拼经济、搞创新”的时代大背景下&#xff0c;人民政协的力量会如何助推长沙建设全球研发中心城市呢&#xff1f; 这是笔者此前一直很好奇的两个问题。8月24日&#xff0c;一场由长沙市政协举办的…

FFmpeg解码32k大分辨率出现如下错误:Picture size 32768x32768 is invalid

最近找到一张32k的jpeg图片&#xff0c;尝试用ffmpeg来进行解码&#xff0c;命令如下&#xff1a; ffmpeg -i enflame_32768-32768-420.jpg 32.yuv结果出现Picture size 32768x32768 is invalid的错误&#xff1a; 找到报错的代码文件imgutils.c&#xff0c;以及函数&#x…

字符串经典问题

1. 验证回文串 验证回文串 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 t…