常用的线程池介绍

线程池:

简介:线程池是用来统一管理线程的,在 Java 中创建和销毁线程都是一件消耗资源的事情,线程池可以重复使用线程,不再频繁的创建、销毁线程。

线程池的作用是提高系统的性能和线程的利用率,不再需要频繁的创建和销毁线程。如果使用最简单的方式创建线程,在用户量巨大的情况下,消耗的性能是非常恐怖的,所以才有了线程池。

ThreadPoolExecutor

常用的线程池介绍
  • Executor: 代表线程池的接口,有一个 execute() 方法,给一个 Runnable 类型对象就可以分配一个线程执行。

java;gutter:true; void execute(Runnablecommand);</p> <pre><code> * ExecutorService:是 Executor 的子接口,提供了线程池的一些生命周期方法。代表了一个线程池管理器。 ![常用的线程池介绍](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/2161450-20220817173520283-1039162726.png) * ThreadPoolExecutor:一个线程池的实现类,可以通过调用 Executors 静态工厂方法来创建线程池并返回一个 ExecutorService 对象。 ![常用的线程池介绍](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/2161450-20220817173529058-809491849.png) 从源码中可以看出每个前三个构造函数都调用了最后一个构造函数。 </code></pre> <p>public ThreadPoolExecutor(int corePoolSize,</p> <pre><code> int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { //省略代码 } </code></pre> <pre><code> 仔细分析一下构造参数: 1. corePoolSize:线程池里的核心线程数量,当正在运行的线程数量小于核心线程数量,就创建一个核心线程。 2. maximumPoolSize:线程池最多能放多少个线程。 3. keepAliveTime:线程的闲置时间,当线程池里面的线程数量大于 corePoolSize 的时候,多出来的线程在等待的时间之后会被释放掉 4. unit:keepAliveTime 的单位 5. workQueue:一个阻塞队列。 6. threadFactory:通过这个工厂模式创建线程。 7. handler:处理线程队列满了报错的。 结合线程池的参数简单的画出线程池的工作模型。 ![常用的线程池介绍](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/2161450-20220817173736371-1013875382.png) 当线程池中的核心线程数量 corePoolSize 满了,就会将任务先加入到任务队列 workQueue 中。 ## 执行过程 ![常用的线程池介绍](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/2161450-20220817173806585-796880588.png) ## 常用的线程池 ### ThredadPoolExcutor ### SingleThreadExecutor 单线程的线程池,里面就一个核心线程数。只有一个线程在跑。 </code></pre> <p>public static ExecutorService newSingleThreadExecutor() {</p> <pre><code>return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); </code></pre> <p>}</p> <p>public class TodoDemo implements Runnable {</p> <pre><code>public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); for(int i = 0; i < 10; i++) { executorService.execute(new TodoDemo()); } executorService.shutdown(); } @Override public void run() { System.out.println(Thread.currentThread().getName() + " Running"); } </code></pre> <p>}</p> <pre><code> ### FixedThreadExecutor 这个线程池的特点就是线程的数量是固定的,超过这个数量的任务就得在 LinkedBlockingQueue 中排队等候。 </code></pre> <p>return new ThreadPoolExecutor(nThreads, nThreads,</p> <pre><code> 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); </code></pre> <p>}</p> <p>public class TodoDemo implements Runnable {</p> <pre><code>public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); for(int i = 0; i < 10; i++) { executorService.execute(new TodoDemo()); } executorService.shutdown(); } @Override public void run() { System.out.println(Thread.currentThread().getName() + " Running"); } </code></pre> <p>}</p> <pre><code> ### CachedThreadExecutor 自动回收空闲的线程,核心线程数量为 0, 表示不会永久保留任何的线程,最大线程的数量是 Integer.MAX_VALUE,可以无限制的创建线程,但是当有大量线程处于空闲状态的时候,超过 60s 就会被销毁。虽然这个线程池可以想建多少个线程就建多少个线程,但是还是会重用已经完成任务的线程。 </code></pre> <p>public static ExecutorService newCachedThreadPool() {</p> <pre><code>return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); </code></pre> <p>}</p> <p>public class TodoDemo implements Runnable {</p> <pre><code>public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); for(int i = 0; i < 20; i++) { executorService.execute(new TodoDemo()); } executorService.shutdown(); } @Override public void run() { System.out.println(Thread.currentThread().getName() + " Running"); } </code></pre> <p>}

线程池的回收策略

在线程池中任务队列已经满了,并且线程的数量已经到了最大的数量,这个时候再加任务线程池就不再接受了。

在 ThreadPoolExecutor 里有 4 种拒绝策略,都实现了 RejectedExecutionHandler:

  1. AbortPolicy 表示抛出一个异常。
  2. DiscardPolicy 拒绝任务但是不提示。
  3. DiscardOldestPolicy 丢弃掉老的任务,执行新的任务。
  4. CallerRunsPolicy 直接调用线程处理。

Original: https://www.cnblogs.com/l-926/p/16596112.html
Author: 小新超人
Title: 常用的线程池介绍

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/570213/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring Cloud Alibaba 使用Gateway作为服务网关

    从没有网关的角度来看后台如有N个服务,那么前端则需要对接N个服务;只要后台修改IP或者端口等任何信息那么前端也需要修改。当服务对接了网关后前端只需要统一调用网关入口即可,具体调用那…

    Java 2023年6月5日
    081
  • SpringBoot接口-API接口有哪些不安全的因素?如何对接口进行签名?

    在以SpringBoot开发后台API接口时,会存在哪些接口不安全的因素呢?通常如何去解决的呢?本文主要介绍API 接口有不安全的因素以及 常见的保证接口安全的方式,重点 实践如何…

    Java 2023年6月6日
    0126
  • Spring事件监听机制源码解析

    Spring事件监听器使用 1.Spring事件监听体系包括三个组件:事件、事件监听器,事件广播器。 事件:定义事件类型和事件源,需要继承ApplicationEvent。 pac…

    Java 2023年6月13日
    067
  • 人到中年,做管理真的需要懂的管理必备知识

    课堂三点要求: 认真听讲,记笔记 * – 讲义电子版会给补充,不要急于找资料 – 跟着课堂节奏 积极参与课堂互动,远程依然有温度 * – 课堂提…

    Java 2023年6月16日
    069
  • 君子不立危墙之下

    君子不立危墙之下 出处 孔子的弟子子路要去卫国做大司马,可是卫国国君无力,太子无德,国内权利交错。孔子不赞成子路去,就说:”危邦不入,乱邦不居,天下有道则入,无道则隐。…

    Java 2023年6月9日
    080
  • NO7 创新

    (本文为ppt,可以在文件中看到对应ppt文件) 大哉乾元 2016/7/19 作者原创转载请注明出处 创 新 李海波 (v1.0) 目录 * 什么是创新 * 为什么创新 * 创新…

    Java 2023年6月8日
    076
  • Spring Boot入门系列(二十一)如何优雅的设计 Restful API 接口版本号,实现 API 版本控制!

    前面介绍了Spring Boot 如何快速实现Restful api 接口,并以人员信息为例,设计了一套操作人员信息的接口。不清楚的可以看之前的文章:https://www.cnb…

    Java 2023年5月30日
    088
  • 使用objc4V818.2源码编译,没有什么比苹果底层源码更有说服力去证明底层原理真假

    前言为什么会想要调试源码? 苹果开源了部分源码, 但相似内容太多, 基本找不到代码见的对应关系, 如果能像自己工程一样进行跳转那多好哇~~苹果源码开源地址: https://ope…

    Java 2023年6月16日
    082
  • Day8

    package method;public class Demo4 { public static void main(String[] args) { Demo4 d= new …

    Java 2023年6月5日
    055
  • 【leetcode】 15. 三数之和

    题目 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。 注意…

    Java 2023年6月6日
    0101
  • JAVA不可变List的实现

    有时候方法返回一个列表但是不想调用者改变列表内容。有三种方法可以实现不可变列表,通过调用JDK,Guava以及Apache Commons Collections相关API来实现。…

    Java 2023年5月29日
    065
  • nginx刷新显示404

    1、web单页面开发模式,只有一个index.html入口,其他路径是前端路由去跳转的,nginx没有对应这个路径,所以就会报404了。 2、增加try_files $uri $u…

    Java 2023年5月30日
    079
  • JavaCoreTechnology-1

    反射:能够分析类能力的程序称为反射。 在Java中提供了一个反射库,里面涵盖了大量的丰富精巧的工具集,可以用来编写能够动态操纵Java代码的程序。 在之后的文章中将会介绍到反射的功…

    Java 2023年6月5日
    090
  • 爆肝30天,肝出来史上最透彻Spring原理和27道高频面试题总结

    在阅读面试题之前,小伙伴们可以先看看我之前发布的系列文章,Spring核心原理包括源码分析和用30个类手写。面试刷题固然很重要,但是知其然知其所以然更重要。 1 Spring环境预…

    Java 2023年6月7日
    058
  • 若依系统部分页签点击后刷新页面问题

    问题: ruoyi系统部分页签点击后会刷新页面,但是一部分页签点击后不会刷新页面。 背景: ruoyi前后端分离项目,后端Springboot,前端vue。 解决: 官方文档 同时…

    Java 2023年6月14日
    074
  • G1收集器

    G1之前垃圾收集器预习: https://www.cnblogs.com/fengtingxin/p/13966982.html GC统一语义: 部分收集(Partial GC) …

    Java 2023年6月8日
    061
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球