Java中创建线程池的几种方式以及区别

 更新时间:2024年11月06日 11:01:09   作者:The-Venus  
创建线程池有多种方式,主要通过 Java 的 java.util.concurrent 包提供的 Executors 工具类来实现,本文给大家介绍了几种常见的线程池类型及其区别,并通过代码示例讲解的非常详细,需要的朋友可以参考下

1. FixedThreadPool

//创建一个固定大小的线程池,模拟提交 10 个任务到线程池。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); // 创建一个具有3个线程的固定线程池
        
        for (int i = 1; i <= 10; i++) {
            final int task = i;
            fixedThreadPool.execute(() -> {
                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());
            });
        }
        
        fixedThreadPool.shutdown();
    }
}
  • 特点:创建一个固定大小的线程池,池中始终保持指定数量的线程。

  • 适用场景:适用于固定并发数的任务,比如定量的短期并发任务。

  • 优点:能够有效地控制线程数量,避免资源消耗过多。

  • 缺点:如果所有线程都在执行任务,而新的任务不断提交,可能会造成等待队列过长。

2. CachedThreadPool

//创建一个缓存线程池来处理任务,模拟并发执行 10 个任务

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedThreadPoolExample {
    public static void main(String[] args) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        
        for (int i = 1; i <= 10; i++) {
            final int task = i;
            cachedThreadPool.execute(() -> {
                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());
            });
        }
        
        cachedThreadPool.shutdown();
    }
}
  • 特点:创建一个可以根据需要自动扩展的线程池,当线程空闲 60 秒后会被回收。
  • 适用场景:适合执行大量耗时较短的异步任务。
  • 优点:线程数量不受限制(受系统资源限制),对于任务短小、并发量大但不稳定的场景效果较好。
  • 缺点:如果任务增长过快,会创建大量线程,可能会造成 OOM(Out of Memory)异常。

3. SingleThreadExecutor

//创建一个单线程线程池,顺序执行多个任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadExecutorExample {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        
        for (int i = 1; i <= 5; i++) {
            final int task = i;
            singleThreadExecutor.execute(() -> {
                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());
            });
        }
        
        singleThreadExecutor.shutdown();
    }
}
  • 特点:创建单线程化的线程池,始终只有一个工作线程。
  • 适用场景:适用于需要保证任务顺序执行的场景,避免多线程并发的复杂性。
  • 优点:可以保证任务按顺序执行,适合单一任务队列。
  • 缺点:性能较低,不适合需要高并发的场景。

4. ScheduledThreadPool

//创建一个支持定时和周期性执行任务的线程池,示例任务每隔 2 秒执行一次,共执行 3 次。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2); // 创建一个有2个线程的定时线程池
        
        scheduledThreadPool.scheduleAtFixedRate(() -> {
            System.out.println("定时任务执行,线程:" + Thread.currentThread().getName());
        }, 0, 2, TimeUnit.SECONDS); // 0秒延迟后开始,每隔2秒执行一次任务
        
        // 程序运行5秒后关闭线程池
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        scheduledThreadPool.shutdown();
    }
}
  • 特点:创建一个支持定时或周期性任务执行的线程池。
  • 适用场景:适合执行定时任务或周期性任务,比如定时器、定时检查等。
  • 优点:可以方便地实现周期性任务管理。
  • 缺点:对高并发任务的处理能力较弱,通常用于任务量不大的场景。

5. WorkStealingPool(Java 8 引入)

//创建一个基于任务分解的线程池来并行执行多个任务,适合处理需要拆分的小任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class WorkStealingPoolExample {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService workStealingPool = Executors.newWorkStealingPool(); // 创建默认线程数为CPU核心数的工作窃取线程池
        
        for (int i = 1; i <= 8; i++) {
            final int task = i;
            workStealingPool.submit(() -> {
                System.out.println("执行任务 " + task + ",线程:" + Thread.currentThread().getName());
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        
        // 让主线程等待子任务执行完成
        workStealingPool.awaitTermination(3, TimeUnit.SECONDS);
        workStealingPool.shutdown();
    }
}
  • 特点:基于 ForkJoinPool 实现,适用于大任务拆分成小任务的并行处理。线程数默认为处理器核心数。
  • 适用场景:适合处理较为复杂的并行任务,比如分治算法。
  • 优点:通过“工作窃取”算法实现任务的动态负载均衡,能够有效提升多核 CPU 的利用率。
  • 缺点:由于线程数不固定,可能对资源使用较多,不适合所有应用。

区别总结

线程池类型线程数量控制特点适用场景
FixedThreadPool固定数量固定线程数,适合稳定的任务并发固定并发任务
CachedThreadPool自动扩展动态扩展,空闲线程自动回收,适合任务短小但并发量不稳定短期的异步并发任务
SingleThreadExecutor单一线程单线程顺序执行任务,保证顺序顺序执行的任务
ScheduledThreadPool可控核心线程数支持定时或周期性任务定时任务、周期性任务
WorkStealingPool默认 CPU 核数基于任务拆分并行处理,提高多核 CPU 利用率并行计算和多任务的分解

以上就是Java中创建线程池的几种方式以及区别的详细内容,更多关于Java创建线程池的资料请关注脚本之家其它相关文章!

相关文章

  • SpringBoot下获取resources目录下文件的常用方法

    SpringBoot下获取resources目录下文件的常用方法

    本文详细介绍了SpringBoot获取resources目录下文件的常用方法,包括使用this.getClass()方法、ClassPathResource获取以及hutool工具类ResourceUtil获取,感兴趣的可以了解一下
    2024-10-10
  • java通过方向键控制小球移动的小游戏

    java通过方向键控制小球移动的小游戏

    这篇文章主要为大家详细介绍了java通过方向键控制小球移动的小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Java之多个线程顺序循环执行的几种实现

    Java之多个线程顺序循环执行的几种实现

    这篇文章主要介绍了Java之多个线程顺序循环执行的几种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java数据结构(线性表)详解

    Java数据结构(线性表)详解

    本文主要介绍了Java数据结构(线性表)的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • java实现爬取知乎用户基本信息

    java实现爬取知乎用户基本信息

    这篇文章主要为大家介绍了一个基于JAVA的知乎爬虫,抓取知乎用户基本信息,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Java for循环几种写法整理

    Java for循环几种写法整理

    这篇文章主要介绍了Java for循环几种写法整理的相关资料,需要的朋友可以参考下
    2017-02-02
  • 解决springboot+shiro 权限拦截失效的问题

    解决springboot+shiro 权限拦截失效的问题

    这篇文章主要介绍了解决springboot+shiro 权限拦截失效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java设计模式模板方法模式(Template)用法解析

    Java设计模式模板方法模式(Template)用法解析

    这篇文章主要介绍了Java设计模式模板方法模式(Template)用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • SpringBoot 微信退款功能的示例代码

    SpringBoot 微信退款功能的示例代码

    这篇文章主要介绍了SpringBoot 微信退款功能的实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 基于SpringBoot使用MyBatis插件的问题

    基于SpringBoot使用MyBatis插件的问题

    MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可以使用MyBatisX插件,今天小编给大家带来了SpringBoot使用MyBatis插件问题,感兴趣的朋友一起看看吧
    2022-03-03

最新评论