线程池是什么?线程池(ThreadPoolExecutor)使用详解

article/2025/9/10 8:36:02

点一点,了解更多https://www.csdn.net/

本篇文章将详细讲解什么是线程池,线程池的参数介绍,线程池的工作流程,使用Executors创建常见的线程池~~~

目录

点一点,了解更多

文章目录

一、线程池的概念

1.1线程池的目的-提高效率

二、线程池的参数介绍

2.1线程池的拒绝策略

以上四种策略要重点掌握,面试常考~~

三、线程池的工作流程

四、线程池的创建

4.1方法一 

 4.2方法二 

4.3方法三

4.4方法四

4.5方法五

4.6方法六

4.7方法七

五、模拟实现一个线程池


一、线程池的概念

简单来说,可以理解为一个“现成的池子”,里面有一定数量的线程等待工作,每次使用不用再次创建、使用完了不用马上销毁,会自动回收进池子中。类似常量池等等~~

虽然创建销毁线程比创建销毁进程更轻量, 但是在频繁创建销毁线程的时候还是会比较低效,线程池就是为了解决这个问题,如果某个线程不再使用了,并不是真正把线程释放,而是放到一个“池子”中,下次如果需要用到线程就直接从池子中取,不用再次创建。

1.1线程池的目的-提高效率

池的目的就是为了提高效率,从线程池中拿线程,属于用户态操作;而从系统再去创建线程,涉及到用户态和内核态之间的切换,真正的创建是在内核态完成的。

那么什么是用户态?什么是内核态?下面我来举个例子:

银行中有大厅和服务柜台,大厅相当于用户态,柜台相当于内核态;每个地方都有打印机,如果来客户需要办理业务,可以在打印机上办理,也可以找工作人员办理。

此时来个老哥,说想办个银行卡,但是没带身份证复印件,有俩个办法:1.自己去大厅的复印件,自己复印一份,拿过来。2.让工作人员去柜台里面的打印机,去复印下再拿回来。

那么如果自己去复印,就立即去了,立即回来了,中间不耽误;如果工作人员去复印,他可能会做点别的,确实能给你复印,但是就不一定及时了~~

结论:用户态操作,时间是可控的;涉及到内核态操作,时间就不可控了~~

二、线程池的参数介绍

先看ThreadPoolExecutor 的构造方法

重点理解一下这几个参数含义:先情景带入一下,把线程池当作公司,一类正式员工;一类实习生;

1.corePoolSize:核心线程数,相当于正式员工

2.maxinumPoolSize:最大线程数,相当于正式员工+实习生

3.

long keepAliveTime:实习生线程保持存活的时间 

当任务比较少的时候,整体比较空闲,实习生不是立即被辞退的,表示实习生最大的存活时间

4.

TimeUnit unit:单位,秒,分钟,毫秒

5. 

BlockingQueue<Runnable> workQueue:线程池里要管理很多任务,这些任务也是通过阻塞队列来组织的,此时可以手动指定一个队列给线程池,此时就可以很方便的获取队列中的信息

6.

ThreadFactory threadFactory:工厂模式,创建线程的辅助的类

7.

RejectedExecutionHandler handler:线程池的拒绝策略,如果任务量超出公司的负荷接下来该怎么处理

2.1线程池的拒绝策略

上述四种是标准库中提供的四种拒绝策略:

1.

表示如果队列满了,继续添加任务, 添加操作之间抛出异常(新老都执行不了,哭)

2.

添加的线程自己负责执行这个任务(怼回去)

3.

丢弃最老的任务

4. 丢弃最新的任务 

以上四种策略要重点掌握,面试常考~~

三、线程池的工作流程图

四、线程池的创建

  • ExecutorService 表示一个线程池实例
  • Executors 是一个工厂类, 能够创建出几种不同风格的线程池
  • ExecutorService 的 submit 方法能够向线程池中提交若干个任务
  • Executors 本质上是 ThreadPoolExecutor 类的封装

4.1方法一 

创建具有十个线程的线程池(大小固定)

public class ThreadDemo {public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(10);pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});}
}

 4.2方法二 

创建一个操作无界队列且只有一个工作线程的线程池

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

4.3方法三

用来处理大量短时间工作任务的线程池,如果池中没有可用的线程将创建新的线程,如果线程空闲60秒将收回并移出缓存,创建线程数目动态增长的线程池

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

4.4方法四

创建一个单线程执行器,可以在给定时间后执行或定期执行。

 ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();

4.5方法五

创建一个指定大小的线程池,可以在给定时间后执行或定期执行,是进阶版的Timer

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

4.6方法六

 创建一个指定大小(不传入参数,为当前机器CPU核心数)的线程池,并行地处理任务,不保证处理顺序

Executors.newWorkStealingPool();

4.7方法七

自定义线程池,工作中使用这种方法创建线程池

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,10,10000,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());

五、模拟实现一个线程池

设置一个具有十个线程的线程池,打印0-1000个数。

其中在构造方法中调用十个线程执行,submit方法进行放入任务!!

class MyThreadPool{private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}public MyThreadPool(int n){for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {try {while (true){Runnable runnable = queue.take();runnable.run();}} catch (InterruptedException e) {e.printStackTrace();}});t.start();}}
}
public class ThreadDemo {public static void main(String[] args) throws InterruptedException {MyThreadPool pool = new MyThreadPool(10);for (int i = 0; i < 1000; i++) {int number = i;pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello "+ number);}});}Thread.sleep(3000);}
}

可见,线程池中任务的执行的顺序和添加顺序不一定相同,因为这十个线程是无序调度的


http://chatgpt.dhexx.cn/article/Lg88WO6N.shtml

相关文章

写给小白看的线程池,还有10道面试题

如何搞定20k的面试小抄 为什么要用线程池呢&#xff1f; 下面是一段创建线程并运行的代码: for (int i 0; i < 100; i) {new Thread(() -> {System.out.println("run thread->" Thread.currentThread().getName());userService.updateUser(....);}).start…

线程池详解(通俗易懂超级好)

目标 【理解】线程池基本概念 【理解】线程池工作原理 【掌握】自定义线程池 【应用】java内置线程池 【应用】使用java内置线程池完成综合案例 线程池 线程池基础线程池使用线程池综合案例学员练习线程池总结 概念介绍 什么是线程池为什么使用线程池线程池有哪些优势 什么…

Java 多线程:彻底搞懂线程池

熟悉 Java 多线程编程的同学都知道&#xff0c;当我们线程创建过多时&#xff0c;容易引发内存溢出&#xff0c;因此我们就有必要使用线程池的技术了。 目录 1 线程池的优势 2 线程池的使用 3 线程池的工作原理 4 线程池的参数 4.1 任务队列&#xff08;workQueue&#x…

GridView概述

一、使用GridView以表格形式显示多张图片 GridView用于在界面上按行、列分布的方式来显示多个组件 二、使用GridView 1、java代码 import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterV…

Master-Detail GridView

梦幻版Master-Detail GridView(黄忠成) 2007-12-26 09:34 前面的Master-Detail GridView控件應用&#xff0c;相信你已在市面上的書、或網路上見過&#xff0c;但此節中的GridView控件應用包你沒看過&#xff0c;但一定想過&#xff01;請見圖4-8-63。 圖4-8-63 圖 4-8-64 你一…

GridView DataGrid

ASP.NET 2.0提供了功能强大的数据绑定控件GridView、在使用中&#xff0c;一些属性和方法经常会与ASP.NET 1.1中的DataGrid混淆(VS2005中依然可以使用DataGrid&#xff0c;手动添加到工具箱或HTML状态输入代码)&#xff0c;下面我们分别用GridView和DataGrid实现其数据绑定、编…

GridView详讲

GridView是ASP.NET界面开发中的一个重要的控件&#xff0c;对GridView使用的熟练程度直接影响软件开发的进度及功能的实现。(车延禄) GridView的主要新特性&#xff1a; 1.与DataSource控件结合实现了显示与数据操作的分离&#xff0c;大大减化了代码的编写量; 2.实现"双向…

GridView详述

GridView无代码分页排序GridView选中&#xff0c;编辑&#xff0c;取消&#xff0c;删除GridView正反双向排序GridView和下拉菜单DropDownList结合GridView和CheckBox结合鼠标移到GridView某一行时改变该行的背景色方法一鼠标移到GridView某一行时改变该行的背景色方法二GridVi…

GridView、ListView、Adapter、Map、HashMap

1.ListView自定义适配器adapter 注&#xff1a;Android适配器是数据和视图之间的桥梁&#xff0c;以便于数据在View上显示。适配器就像显示器&#xff0c;把复杂的东西按人可以接受的方式来展现。 &#xff08;1&#xff09;首先将适配器的View视图表现出来&#xff0c;使用L…

GridViewPager

GridViewPager ViewPager结合GridView&#xff0c;轻松实现类似表情面板的控件。可自由定制Item布局&#xff0c;提供充足的自定义参数等。也处理了条目点击事件和条目长按事件。效果如下&#xff1a; Demo下载地址&#xff1a;GridViewPager &#xff0c;或者扫描以下二维码…

libevent 编译

1.下载源码 github:https://github.com/libevent/libevent 官网&#xff1a;http://libevent.org/ 2.CMake 编译 在libevent源码目录建立文件夹&#xff1a;BuildVs2010_x64 2.打开CMake 3.BuildVs2010_x64 下此时生成了vs2010的解决方案。然后编译生成就ok NOTE&#x…

13、《Libevent中文帮助文档》学习笔记13:Linux下集成、运行libevent

Linux下编译libevent的指导可以参考《4、《Libevent中文帮助文档》学习笔记4&#xff1a;Linux下编译libevent》&#xff0c;完成编译、安装&#xff0c;生成so库后&#xff0c;其他程序即可依赖libevent的so库&#xff0c;使用libevent的功能。 由于没有通过prefix指定安装路…

libevent 编译与安装 (WIN10 visual studio2019, ubuntu,centos)

文章目录 一、准备安装包二、编译与安装编译zlib编译openssl编译libevent 三、libevent集成zlib测试程序修改编译&#xff08;可选&#xff09;四、测试程序五、linux(ubuntu)测试安装依赖环境&#xff0c;依次编译zlib,openssl,libeventwindows与linux共享文件夹&#xff08;使…

Libevent 学习一:Libevent 源码编译

文章目录 Libevent 学习一&#xff1a;Libevent 源码编译Libevent Windows 编译Windows 编译环境安装 Visual Studio Community 2015安装 zlib安装 OpenSSL安装 Libeventcmake 安装 LibeventLibevent 测试程序 Libevent Linux编译CentOS 7 安装 LibeventLibevent 测试程序 Libe…

libevent mysql_libevent安装总结

1.先用&#xff1a;ls -al /usr/lib | grep libevent 查看是否已安装&#xff1b;如果已安装且版本低于1.3&#xff0c;则先通过&#xff1a;rpm -e libevent —nodeps进行卸载。 2.下载libevent安装包&#xff1a;libevent-2.0.18-stable.tar.gz。 wget https://github.com/do…

在window用vcpkg安装libevent

参考readme https://github.com/microsoft/vcpkg/blob/master/README_zh_CN.md 使用的PackageManager方式安装&#xff0c; Package Managers 下载 vcpkg 依赖管理包 git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.bat ./vcpkg integrate…

libevent实践01:准备源码、搭建项目、编译脚本和入门例子

编译源码 libevent是一个Reactor事件库。 我的理解&#xff0c;就是封装了select、epoll、poll的函数库。有使用select&#xff0c;poll&#xff0c;epoll的需求就可以使用的。 官网地址&#xff1a;https://libevent.org/ 下载源码&#xff1a; https://github.com/libev…

libevent(1)windows下安装libevent

Socket通信库libevent成熟、稳定、性能高&#xff0c;在unix和windows下都能使用&#xff0c;在证券交易领域也有不少成功的应用&#xff0c;已经用事实证明是非常棒的socket通信库。对我们目前交易系统的unix重构来说&#xff0c;是比较合适的选择 –– 坑少、在证券交易项目中…

Libevent库的学习

目录 Libevent 概述 Libevent 使用模型 使用Libevent的基本流程&#xff1a; libevent 的核心&#xff0c;event 事件 1. 创建一个事件event 2. 释放event_free 3. 注册event 4. 信号事件 5. 销毁event_base Libevent 结构图 使用libevent库去实现tcp服务器 Libev…

编译libevent

本文记录在win10编译libevent的过程 1.编译前准备zlib,openssl zlib网址 http://www.zlib.net/ 下载源码解压缩 打开vs的dos窗口 32位选择32位窗口这里选择64位,cd 到解压后的文件夹 执行 nmake /f win32/Makefile.msc 执行后可以看到目录下有lib文件和dll文件和测试文件…