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

ThreadPoolExecutor可以创建哪是哪三种线程池呢?

ThreadPoolExecutor 是一个非常灵活的类,可以根据不同的参数配置来创建不同类型的线程池。尽管它本身没有硬性规定必须创建某三种线程池,但常见的线程池类型通常有以下三种:固定大小线程池、缓存线程池和单线程池。这些常见的线程池类型可以通过 Executors 工具类来创建,并且底层实现都使用了 ThreadPoolExecutor

具体而言,它们可以概括为以下三种:

1. 固定大小线程池(Fixed Thread Pool)

固定大小的线程池,具有固定数量的核心线程,并且不会回收这些线程。此类型的线程池适用于负载较稳定的场景。

创建方式

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(int nThreads);

等价的 ThreadPoolExecutor 配置

int nThreads = 4;
ExecutorService fixedThreadPool = new ThreadPoolExecutor(
        nThreads,
        nThreads,
        0L,
        TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>()
);

2. 缓存线程池(Cached Thread Pool)

缓存线程池可根据需求创建新线程,如果旧线程在指定时间内没有被使用,则会回收这些线程。适用于大量短生命周期的异步任务的场景。

创建方式

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

等价的 ThreadPoolExecutor 配置

ExecutorService cachedThreadPool = new ThreadPoolExecutor(
        0, 
        Integer.MAX_VALUE, 
        60L, 
        TimeUnit.SECONDS, 
        new SynchronousQueue<Runnable>()
);

3. 单线程池(Single Thread Executor)

单线程池内部只有一个线程来执行任务,所有任务会被顺序地执行。适用于需要顺序执行的场景,以及需要保证线程安全的单例任务执行环境。

创建方式

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

等价的 ThreadPoolExecutor 配置

ExecutorService singleThreadExecutor = new ThreadPoolExecutor(
        1, 
        1, 
        0L, 
        TimeUnit.MILLISECONDS, 
        new LinkedBlockingQueue<Runnable>()
);

4. 调度线程池(Scheduled Thread Pool)

除了上面的三种常见线程池类型之外,ThreadPoolExecutor 还用于实现调度线程池(ScheduledThreadPool),这类线程池可以用于调度定时任务。

创建方式

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(int corePoolSize);

底层实现

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(
        corePoolSize,
        Integer.MAX_VALUE,
        0,
        NANOSECONDS,
        new DelayedWorkQueue()
    );
}

示例代码

举例说明如何使用 ThreadPoolExecutor 配置不同的线程池:

import java.util.concurrent.*;

public class DifferentThreadPoolsExample {
    public static void main(String[] args) {
        // 固定大小线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);

        // 提交任务
        for (int i = 0; i < 10; i++) {
            final int taskNumber = i;
            fixedThreadPool.submit(() -> {
                try {
                    System.out.println("Fixed Task " + taskNumber + " is running by " + Thread.currentThread().getName());
                    Thread.sleep(2000);
                    System.out.println("Fixed Task " + taskNumber + " is completed by " + Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        // 缓存线程池
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i;
            cachedThreadPool.submit(() -> {
                try {
                    System.out.println("Cached Task " + taskNumber + " is running by " + Thread.currentThread().getName());
                    Thread.sleep(2000);
                    System.out.println("Cached Task " + taskNumber + " is completed by " + Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        // 单线程池
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i;
            singleThreadExecutor.submit(() -> {
                try {
                    System.out.println("Single Task " + taskNumber + " is running by " + Thread.currentThread().getName());
                    Thread.sleep(2000);
                    System.out.println("Single Task " + taskNumber + " is completed by " + Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        // 通过 shutdown 关闭线程池
        fixedThreadPool.shutdown();
        cachedThreadPool.shutdown();
        singleThreadExecutor.shutdown();
        
        // 延时调度线程池(额外的)
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
        
        scheduledExecutorService.schedule(() -> {
            System.out.println("Scheduled Task is running by " + Thread.currentThread().getName());
        }, 5, TimeUnit.SECONDS);
        
        scheduledExecutorService.shutdown();
    }
}

总结

虽然上面常见的三种线程池类型是最常用的,但 ThreadPoolExecutor 的灵活性使您可以创建几乎任何类型的线程池以适应特定的应用需求。理解这些基本类型的工作原理和适用场景将有助于在实际项目中更有效地使用线程池。


http://www.kler.cn/news/367990.html

相关文章:

  • nginx配置本地缓存用于提高响应效率
  • 论文阅读(二十六):Dual Attention Network for Scene Segmentation
  • fetch: 取消请求、读取流、获取下载进度...
  • C语言实现Go的defer功能
  • ELK之路第一步——Elasticsearch集群的搭建以及踩坑记录
  • Spring Boot驱动的厨艺社交平台设计与实现
  • linux网络编程4——WebSocket协议及服务器的简易实现
  • 苏州金龙技术创新赋能旅游新质生产力
  • Navicat导入Excel数据时数据被截断问题分析与解决方案
  • 论文阅读与写作入门
  • mit6824-03-GFS论文记录
  • 微信小程序版本更新管理——实现自动更新
  • Linux复习-C++
  • vue3组件通信--props
  • 虚拟现实新纪元:VR/AR技术将如何改变娱乐与教育
  • 桥接模式,外界与主机通,与虚拟机不通
  • 提示词高级阶段学习day3.3如何写好结构化 Prompt ?
  • AndroidStudio Koala更改jdk版本 2024-1-2
  • 关于我的数据库——MySQL——第二篇
  • Qt/C++路径轨迹回放/回放每个点信号/回放结束信号/拿到移动的坐标点经纬度
  • JavaEE初阶---多线程(三)---内存可见性/单例模式/wait,notify的使用解决线程饿死问题
  • ubuntu虚拟机网络配置
  • C++STL之stack
  • 二十、行为型(访问者模式)
  • Java学习Day53:铲除紫云山金丹原料厂厂长(手机快速登录、权限控制)
  • 浅谈AI大模型的数据特点和应用问题