线程池(一)线程池的基本使用

article/2025/9/10 3:47:17

一、线程池简介

  • 线程池的概念
    线程池就是首先创建一些线相衬,它们的集合称为线程池,使用线程池可以很好的提高性能,线程池在系统启动时既创建大量空闲的线程,程序将一个任务传给线程池。线程池就会启动一条线程来执行这个任务,执行结束后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

  • 线程池的工作机制
    在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程
    一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务

  • 使用线程池的原因
    多线程运行时间,系统不断的启动和关闭新线程,成本非常高,会过度消耗系统资源,以及过渡切换线程的危险,从而导致系统资源的崩溃,这时,线程池也就是最好的选择了。

二、四种常见的线程池详解

  • 线程池的返回值ExecutorService简介

    ExecutorService是Java提供的用于管理线程池的类。该类的两个作用:控制线程数量和重用线程

  • 具体的4种常用的线程池实现

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

示例代码如下:

public class ThreadPoolExecutorDemo {public static void main(String[] args){//创建可缓存线程池ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {try {//sleep可明显看到使用的是线程池里面以前的线程,没有创建新的线程Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}cachedThreadPool.execute(new Runnable() {@Overridepublic void run() {//打印正在执行的缓存线程信息System.out.println(Thread.currentThread().getName() + "正在被执行1");}});}}
}

在这里插入图片描述
线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

  • Executors.newFixedThreadPool(int n)
    创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

执行示例代码如下:

public class ThreadPoolExecutorDemo {public static void main(String[] args){//创建一个可重用固定个数的线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);for (int i = 0; i < 10; i++) {fixedThreadPool.execute(new Runnable() {@Overridepublic void run() {try {//打印正在执行的缓存线程信息System.out.println(Thread.currentThread().getName()+"正在被执行");Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}});}}
}

在这里插入图片描述
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。可参考PreloadDataCache。

  • Executors.newScheduledThreadPool(int n)
    创建一个定长线程池,支持定时及周期性任务执行。

延迟执行示例代码如下:

public class ThreadPoolExecutorDemo {public static void main(String[] args) {//创建一个定长线程池,支持定时及周期性任务执行——延迟执行ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);//延迟1秒执行scheduledThreadPool.schedule(new Runnable() {@Overridepublic void run() {System.out.println("延迟5秒执行");}}, 5, TimeUnit.SECONDS);}
}

表示延迟5秒执行。

定期执行示例代码如下:

public class ThreadPoolExecutorDemo {public static void main(String[] args) {//创建一个定长线程池,支持定时及周期性任务执行——延迟执行ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);//延迟1秒执行scheduledThreadPool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("延迟1秒后每3秒执行一次");}}, 1, 3, TimeUnit.SECONDS);}
}

表示延迟1秒后每3秒执行一次
在这里插入图片描述
TimeUnit类

TimeUnit.DAYS          //天
TimeUnit.HOURS         //小时
TimeUnit.MINUTES       //分钟
TimeUnit.SECONDS       //秒
TimeUnit.MILLISECONDS  //毫秒
  • Executors.newSingleThreadExecutor()
    创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

示例代码如下:

public class ThreadPoolExecutorDemo {public static void main(String[] args) {//创建一个单线程化的线程池ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {final int index = i;singleThreadExecutor.execute(new Runnable() {@Overridepublic void run() {try {//结果依次输出,相当于顺序执行各个任务System.out.println(Thread.currentThread().getName()+"正在被执行,打印的值是:"+index);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});}}
}

在这里插入图片描述

三、缓冲队列BlockingQueue和自定义线程池ThreadPoolExecutor

  • 缓冲队列BlockingQueue简介:
    BlockingQueue是双缓冲队列。BlockingQueue内部使用两条队列,允许两个线程同时向队列一个存储,一个取出操作。在保证并发安全的同时,提高了队列的存取效率。
  • 常用的几种BlockingQueue:
  1. ArrayBlockingQueue(int i):规定大小的BlockingQueue,其构造必须指定大小。其所含的对象是FIFO顺序排序的。
  2. LinkedBlockingQueue()或者(int i):大小不固定的BlockingQueue,若其构造时指定大小,生成的BlockingQueue有大小限制,不指定大小,其大小有Integer.MAX_VALUE来决定。其所含的对象是FIFO顺序排序的。
  3. PriorityBlockingQueue()或者(int i):类似于LinkedBlockingQueue,但是其所含对象的排序不是FIFO,而是依据对象的自然顺序或者构造函数的Comparator决定。
  4. SynchronizedQueue():特殊的BlockingQueue,对其的操作必须是放和取交替完成。
  • 自定义线程池(ThreadPoolExecutor和BlockingQueue连用)

    自定义线程池,可以用ThreadPoolExecutor类创建,它有多个构造方法来创建线程池。
    常见的构造函数:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)

示例代码:

public class TempThread implements Runnable{@Overridepublic void run() {// 打印正在执行的缓存线程信息System.out.println(Thread.currentThread().getName() + "正在被执行");try {// sleep一秒保证3个任务在分别在3个线程上执行Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}
}
public class TestThreadPoolExecutor {public static void main(String[] args) {// 创建数组型缓冲等待队列BlockingQueue<Runnable> bq = new ArrayBlockingQueue<Runnable>(10);// ThreadPoolExecutor:创建自定义线程池,池中保存的线程数为3,允许最大的线程数为6ThreadPoolExecutor tpe = new ThreadPoolExecutor(3, 6, 50, TimeUnit.MILLISECONDS, bq);// 创建3个任务Runnable t1 = new TempThread();Runnable t2 = new TempThread();Runnable t3 = new TempThread();// 3个任务在分别在3个线程上执行tpe.execute(t1);tpe.execute(t2);tpe.execute(t3);// 关闭自定义线程池tpe.shutdown();}
}

在这里插入图片描述

ThreadPoolExecutor构造参数解析

序号名称类型含义
1corePoolSizeint核心线程池大小
2maximumPoolSizeint最大线程池大小
3keepAliveTimelong线程最大空闲时间
4unitTimeUnit时间单位
5workQueueBlockingQueue<Runnable>线程等待队列
6threadFactoryThreadFactory线程创建工厂
7handlerRejectedExecutionHandler拒绝策略

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

相关文章

线程池介绍及创建线程池的4种方式

1. 什么是线程池 Java中的线程池是运用场景最多的并发框架&#xff0c;几乎所有需要异步或并发执行任务的程序 都可以使用线程池。在开发过程中&#xff0c;合理地使用线程池能够带来3个好处。 第一&#xff1a;降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成…

线程池的使用

1.线程池使用场景 java中经常需要用到多线程来处理一些业务&#xff0c;我们非常不建议单纯使用继承Thread或者实现Runnable接口的方式来创建线程&#xff0c;那样势必有创建及销毁线程耗费资源、线程上下文切换问题。同时创建过多的线程也可能引发资源耗尽的风险&#xff0c;这…

线程池_线程池详解

1 线程池使用场景&#xff1f; java中经常需要用到多线程来处理一些业务&#xff0c;我们非常不建议单纯使用继承Thread或者实现Runnable接口的方式来创建线程&#xff0c;那样势必有创建及销毁线程耗费资源、线程上下文切换问题。同时创建过多的线程也可能引发资源耗尽的风险&…

Netty 线程池

Netty的线程池有什么样的特性 Java 原生线程池 Java 原生的线程池主要有三种&#xff1a;ThreadPoolExecutor、ScheduledThreadPoolExecutor、ForkJoinPool。 ThreadPoolExecutor 是最古老的类&#xff0c;我们通常说的线程池&#xff0c;也是指这个类。 ScheduledThreadPoo…

Linux —— 线程池

目录 一、什么是线程池 二、线程池的优点 三、线程池的应用 四、实现一个简单的线程池 五、单例模式 1. 饿汉实现方式 2. 懒汉实现方式 3. 单例模式实现线程池&#xff08;懒汉方式&#xff09; 六、其他常见的各种锁 一、什么是线程池 线程池是线程的一种使用模式。在…

线程池的实现原理

系统学习性&#xff0c;移步 IT-BLOG 线程池做的工作主要是控制运行的线程数量&#xff0c;处理过程中将任务放入队列&#xff0c;然后在线程创建后启动这些任务&#xff0c;如果线程数超过了最大数量超出数量的线程排队等候&#xff0c;等其他线程执行完毕&#xff0c;再从队列…

java——线程池

一、线程池 线程池可以看做是线程的集合。它的工作主要是控制运行的线程的数量&#xff0c;处理过程中将任务放入队列&#xff0c;然后在线程创建后 启动这些任务&#xff0c;如果线程数量超过了最大数量超出数量的线程排队等候&#xff0c;等其它线程执行完毕&#xff0c; 再…

java线程池(详解)

线程池介绍 线程池&#xff08;thread pool&#xff09;&#xff1a;一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;对线程统一管理。 线程池就是存放线程的池子&#xff0c;池子里存放了很多可以复…

Java线程池详解

本文包含知识点 线程池的使用场景分析线程池的创建及重要参数线程池实现线程复用的原理springboot中使用线程池Callabel与Runnable任务在基于spring体系的业务中正确地关闭线程池实现优先使用运行线程及调整线程数大小的线程池(线程池的优化)在java web项目中慎用Executors以及…

C++线程池

1.基础概念 线程池&#xff1a;一种线程的使用模式&#xff0c;线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性。而线程池维护着多个线程&#xff0c;等待监督管理者分配可并行执行的任务。这样避免了在短时间内创建和销毁线程的代价。线程池不仅能够内核的充分…

线程池详解

成功不是将来才有的&#xff0c;而是从决定去做的那一刻起&#xff0c;持续累积而成。 目录 背景 线程池介绍 线程池使用 Executors 线程池如何关闭&#xff1f; 面试题 总结 背景 下面是一段创建线程并运行的代码: for (int i 0; i < 100; i) {new Thread(() -&…

线程池(通俗易懂)

目录 一、什么是线程池 二、创建线程池的方式 三、线程池的七大参数 四、四种拒绝策略 1.AbortPolicy() 2.CallerRunsPolicy() 3.DiscardPolicy() 4.DiscardOldestPolicy() 五、自定义一个线程池 1.场景描述 2.代码实现 一、什么是线程池 线程池其实就是一种多线程处理…

线程池研发学习笔记

线程池研发 线程池 线程池基础 概念介绍 1:什么是线程池 可以直接叙述,也可以对比连接池介绍 线程池其实就是一种多线程处理形式&#xff0c;处理过程中可以将任务添加到队列中&#xff0c;然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是…

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

点一点&#xff0c;了解更多https://www.csdn.net/ 本篇文章将详细讲解什么是线程池&#xff0c;线程池的参数介绍&#xff0c;线程池的工作流程&#xff0c;使用Executors创建常见的线程池~~~ 目录 点一点&#xff0c;了解更多 文章目录 一、线程池的概念 1.1线程池的目的…

写给小白看的线程池,还有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实现其数据绑定、编…