【Java 并发秘籍】线程池大作战:揭秘 JDK 中的线程池家族!

简介: 【8月更文挑战第24天】Java的并发库提供多种线程池以应对不同的多线程编程需求。本文通过实例介绍了四种主要线程池:固定大小线程池、可缓存线程池、单一线程线程池及定时任务线程池。固定大小线程池通过预设线程数管理任务队列;可缓存线程池能根据需要动态调整线程数量;单一线程线程池确保任务顺序执行;定时任务线程池支持周期性或延时任务调度。了解并正确选用这些线程池有助于提高程序效率和资源利用率。

Java 的并发类库为开发者提供了丰富的工具来处理多线程编程任务,其中线程池是处理并发任务的重要组成部分。线程池可以有效地管理和复用一组线程,避免频繁创建和销毁线程所带来的开销。Java 标准库中提供了多种类型的线程池实现,每种线程池都有其特定的应用场景。本文将以随笔的形式介绍 JDK 中提供的几种线程池实现,并通过示例代码展示它们的使用方法。

固定大小的线程池

固定大小的线程池通过 Executors.newFixedThreadPool(int nThreads) 方法创建。这种线程池中的线程数量是固定的,一旦创建了 n 个线程,这些线程就会一直存活,除非线程池被关闭。当有新的任务提交到线程池时,这些任务会被放入一个队列中,等待线程池中的线程空闲时来执行。

示例代码

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

public class FixedThreadPoolExample {
   
    public static void main(String[] args) {
   
        ExecutorService executor = Executors.newFixedThreadPool(5); // 创建一个包含5个线程的线程池

        for (int i = 0; i < 10; i++) {
   
            final int taskId = i;
            executor.submit(() -> {
   
                System.out.println("Task ID: " + taskId + " is running on thread: " + Thread.currentThread().getName());
                try {
   
                    Thread.sleep(1000); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown(); // 关闭线程池
    }
}

可缓存线程池

可缓存线程池通过 Executors.newCachedThreadPool() 方法创建。这种线程池的特点是,当线程池中的线程数量超出处理任务所需要的线程数量时,多余的空闲线程会被终止。如果某个线程空闲时间超过 60 秒,那么该线程就会被终止并从线程池中移除。当需要执行新的任务时,如果线程池中有空闲的线程,就直接使用空闲线程;如果没有空闲线程,则创建新的线程。

示例代码

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

public class CachedThreadPoolExample {
   
    public static void main(String[] args) {
   
        ExecutorService executor = Executors.newCachedThreadPool(); // 创建一个可缓存线程池

        for (int i = 0; i < 10; i++) {
   
            final int taskId = i;
            executor.submit(() -> {
   
                System.out.println("Task ID: " + taskId + " is running on thread: " + Thread.currentThread().getName());
                try {
   
                    Thread.sleep(1000); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown(); // 关闭线程池
    }
}

单一线程线程池

单一线程线程池通过 Executors.newSingleThreadExecutor() 方法创建。这种线程池只包含一个线程,因此所有任务都会按照顺序执行。这种线程池非常适合那些需要按顺序处理的任务,例如定时任务或者后台任务队列。

示例代码

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

public class SingleThreadExecutorExample {
   
    public static void main(String[] args) {
   
        ExecutorService executor = Executors.newSingleThreadExecutor(); // 创建一个单一线程线程池

        for (int i = 0; i < 10; i++) {
   
            final int taskId = i;
            executor.submit(() -> {
   
                System.out.println("Task ID: " + taskId + " is running on thread: " + Thread.currentThread().getName());
                try {
   
                    Thread.sleep(1000); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown(); // 关闭线程池
    }
}

定时任务线程池

定时任务线程池通过 Executors.newScheduledThreadPool(int corePoolSize) 方法创建。这种线程池不仅可以执行周期性的任务,还可以在指定的延迟之后执行任务。它非常适合用来处理定时任务。

示例代码

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 executor = Executors.newScheduledThreadPool(5); // 创建一个包含5个线程的定时任务线程池

        Runnable task = () -> System.out.println("Executing task on thread: " + Thread.currentThread().getName());

        // 在5秒后执行任务
        executor.schedule(task, 5, TimeUnit.SECONDS);

        // 每隔3秒重复执行任务
        executor.scheduleAtFixedRate(task, 0, 3, TimeUnit.SECONDS);

        // 在5秒后开始执行任务,每隔3秒重复执行
        executor.scheduleWithFixedDelay(task, 5, 3, TimeUnit.SECONDS);

        // 关闭线程池
        executor.shutdown();
    }
}

总结

通过上述随笔,我们可以了解到 JDK 中提供了多种类型的线程池实现,每种线程池都有其特定的应用场景。选择合适的线程池类型对于优化并发程序的性能至关重要。无论是创建固定大小的线程池、可缓存线程池、单一线程线程池还是定时任务线程池,都需要根据具体的业务需求来确定。熟悉这些线程池的特点和使用方法,可以帮助我们在开发中更加高效地处理并发任务。无论是在日常开发还是面试准备中,掌握这些知识都是非常重要的。

相关文章
|
6月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
187 4
|
6月前
|
缓存 安全 Java
如何理解Java中的并发?
Java并发指多任务交替执行,提升资源利用率与响应速度。通过线程实现,涉及线程安全、可见性、原子性等问题,需用synchronized、volatile、线程池及并发工具类解决,是高并发系统开发的关键基础。(238字)
355 5
|
6月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
324 1
|
6月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
325 1
|
7月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
305 0
|
7月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
486 16
|
8月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
8月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
8月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
605 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡

热门文章

最新文章

下一篇
开通oss服务