当前位置: 首页 > news >正文

【JavaEE】线程池

【JavaEE】线程池

  • 一、引言
      • 1.1 什么是线程池
      • 1.2 为什么要使用线程池
  • 二、ThreadPoolExecutor类
      • 2.1 构造方法
        • 2.1.1 corePoolSize和maximumPoolSize
        • 2.1.2 KeepAliveTime和unit
        • 2.1.3 BlockingQueue<Runnable> workQueue
        • 2.1.4 ThreadFactory threadFactory
        • 2.1.5 RejectedExecutionHandler handler
      • 2.2 模拟拒绝策略
  • 三、线程池的实例
  • 四、模拟实现线程池

博客结尾有此篇博客的全部代码!!!

一、引言

1.1 什么是线程池

线程池是一种用于管理和复用线程的机制,通过线程池可以有效降低线程创建和销毁的开销,提高系统的响应速度和资源利用率,允许任务等待处理!

1.2 为什么要使用线程池

  1. 线程的创建和销毁相比于进程的创建和销毁是微不足道的,但是大量线程的创建和销毁消耗的资源也是不少的。
  2. 线程的创建是由内核控制的,这个操作是不可控的;而从线程池中取线程用,这个操作是可控的。

操作系统=内核+配套的应用程序。一个操作系统只有一份内核,内核为其他应用程序提供服务。

  • 需要内核配合完成的都是不可控的

Java中的线程池主要通过ThreadPoolExecutor类实现,同时提供了Executors工具类来方便地创建不同类型的线程池。

二、ThreadPoolExecutor类

2.1 构造方法

在这里插入图片描述
这里主要讲解第四个构造方法,参数最多,也是面试中最容易问的!
在这里插入图片描述

2.1.1 corePoolSize和maximumPoolSize

int corePoolSize(核心线程数):线程池中始终保持的线程数量,即使它们处于空闲状态。
int maximumPoolSize(最大线程数):线程池允许的最大线程数。

2.1.2 KeepAliveTime和unit

long KeepAlive(空闲线程存活时间)。举例:当提交的任务过多,corePoolSize核心线程数不够,线程池就会创建一些新线程来帮忙处理任务,当这些任务处理完,新创建的线程就空闲下来,如果KeepAlive这段时间没有新任务提交,那么这些新创建的线程就会被终止(除corepoolSize核心线程)
TimeUnit unit:代表时间单位(枚举)
在这里插入图片描述

2.1.3 BlockingQueue workQueue

BlockingQueue workQueue:表示一个线程安全的队列(用来存储执行的任务),支持在队列为空时阻塞获取操作,以及在队列满时阻塞插入操作。

2.1.4 ThreadFactory threadFactory

ThreadFactory threadFactory:ThreadFactory 是一个接口,用于自定义线程的创建方式。它可以帮助你统一管理线程的名称、优先级、守护线程属性和异常处理。

2.1.5 RejectedExecutionHandler handler

RejectedExecutionHandler handler(拒绝策略):是一个接口,用于处理线程池无法执行任务时的情况。当线程池已满且任务队列也已满时,新提交的任务会被拒绝,Java中有四种默认拒绝策略或者实现RejectedExecutionHandler接口自定义策略。
在这里插入图片描述

  1. ThreadPoolExecutor.AbortPolicy(默认策略):任务被拒绝,会抛出 RejectedExecutionException 异常
  2. ThreadPoolExecutor.CallerRunsPolicy:任务被拒绝,会在调用者的线程中运行任务(举例:假设朋友A的电脑坏了,他让我给他帮忙修电脑。但此时我忙着,他就自己动手修电脑)
  3. ThreadPoolExecutor.DiscardOldestPolicy:任务被拒绝,会丢弃队列中最老的任务,然后尝试将新任务加入队列
  4. ThreadPoolExecutor.DiscardPolicy:任务被拒绝,会直接丢弃任务,不抛出异常
  5. 自定义拒绝策略:
class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        
    }
}
  • Runnable r 是被拒绝执行的任务
  • ThreadPoolExecutor executor 是当前的线程池实例。它提供了线程池的运行状态和配置信息

2.2 模拟拒绝策略

   public static void main(String[] args) {
        //当任务队列满则抛出异常
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(
                2,//核心线程数
                4, // 最大线程数
                60, // 空闲线程存活时间
                TimeUnit.SECONDS, // 时间单位
                new LinkedBlockingQueue<>(2), // 任务队列,容量为 2
                Executors.defaultThreadFactory(), // 默认线程工厂
                handler
        );

        for (int i = 0; i < 100; i++) {
            poolExecutor.submit(()->{
                System.out.println( Thread.currentThread().getName());
            });
        }
    }

执行结果:
在这里插入图片描述

三、线程池的实例

ThreadPoolExecutor类实现线程池:允许开发者根据自己需要设定线程池
Executors 工具类:提供了一系列静态方法,用于快速创建不同类型的线程池

图片演示的就是Executors工具类创建线程池!
在这里插入图片描述

  public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 10; i++) {
            int id = i;
            threadPool.submit(() -> {
                System.out.println("hello " + id + ", " 
                + Thread.currentThread().getName());
            });
        }
    }

执行结果:
在这里插入图片描述

四、模拟实现线程池

class MyThreadPoolExecutor {
    //先创建一个阻塞队列用来存储任务
    BlockingQueue<Runnable> queue= new LinkedBlockingQueue<Runnable>();
    //创建一个sumbit方法用来提交Runnable
    public void sumbit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }
    //定义一个构造方法来创建线程池中的线程数
    public MyThreadPoolExecutor(int n){
        for (int i = 0; i < n; i++) {
            Thread thread = new Thread(()->{
                    try {
                        while(true){
                        Runnable task=queue.take();//从队列中取出任务
                        task.run();//执行任务
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

            });
            thread.start();
        }
    }
}

public class Demo5 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPoolExecutor executor = new MyThreadPoolExecutor(5);
        for (int i = 0; i < 5; i++) {
            executor.sumbit(()->{
                System.out.println(Thread.currentThread().getName());
            });
        }
    }
}

此篇博客的全部的代码!!!

相关文章:

  • 人工智能的发展历史
  • OSPF-单区域的配置
  • Python 入
  • (openstack搭建)openstack云平台部署-详细完整教程
  • 【每日学点HarmonyOS Next知识】对话框去掉圆角、数组拼接、自定义对话框依附某个控件、平移动画、页面栈管理
  • (二)企业级监控系统 - ZABBIX 部署
  • STM32-SPI通信协议
  • Visual Studio Code 基本使用指南
  • Ultravox:融合whisper+llama实现audio2text交互
  • 三维仿射变换矩阵
  • 安裝do時出現log file support is not available
  • 【软件测试开发】:软件测试常用函数1.0(C++)
  • 『PostgreSQL』 Ubuntu 系统下PG15的安装与 PGVector 配置指南
  • 在本地部署DeepSeek等大模型时,需警惕的潜在安全风险
  • MongoDB 副本集的健康指标 写关注级别
  • 智谱AI开源CogView4,支持中英文,性能比肩flux!
  • 用Nutch库的HTTP请求写个万能下载程序
  • Spark(8)配置Hadoop集群环境-使用脚本命令实现集群文件同步
  • 时序数据库TimescaleDB基本操作示例
  • 米尔电子-LR3568-烧录鸿蒙
  • 江苏省委组织部副部长高颜已任南京市委常委、组织部部长
  • 自然资源部:不动产登记累计化解遗留问题房屋2000多万套
  • 清雪车司机未拉手刹下车导致溜车被撞亡,事故调查报告发布
  • 上海市税务局回应刘晓庆被举报涉嫌偷漏税:正依法依规办理
  • 车主质疑零跑汽车撞车后AEB未触发、气囊未弹出,4S店:其把油门当刹车
  • 四个“从未如此”使巴以加沙战火绵延时间创下历史之最