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

相关文章
|
4月前
|
设计模式 缓存 安全
【JUC】(6)带你了解共享模型之 享元和不可变 模型并初步带你了解并发工具 线程池Pool,文章内还有饥饿问题、设计模式之工作线程的解决于实现
JUC专栏第六篇,本文带你了解两个共享模型:享元和不可变 模型,并初步带你了解并发工具 线程池Pool,文章中还有解决饥饿问题、设计模式之工作线程的实现
272 2
|
4月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
250 2
|
4月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
266 1
|
5月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
222 0
|
5月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
413 16
|
6月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
6月前
|
Ubuntu Java Android开发
在Ubuntu 18.04上安装与JDK 8兼容的Eclipse版本的步骤。
安装过程结束后,您就可以开始使用Eclipse来开发您的Java项目了,并且确保它与JDK 8兼容无误。这个过程涉及的是一个基本的安装流程,针对使用Java 8的用户,Eclipse的其他配置和插件安装根据个人开发环境和需求来定制。
446 0
|
7月前
|
存储 Ubuntu 安全
在Ubuntu 16.04上安装openjdk-6/7/8-jdk的步骤
在整个安装过程中,你可能需要管理员权限,因此你可能要使用 `sudo` 来获取必要的权限。记得做完每一个步骤后,都要检查输出,以确保没有发生错误,并且每项操作都成功完成。如果在安装过程中遇到问题,查看 `/var/log/` 下的日志文件对于问题的解决可能是有帮助的。
489 21
|
7月前
|
IDE Ubuntu Java
在Ubuntu18.04安装兼容JDK 8的Eclipse集成开发环境的指南。
完成以上步骤后,您将在Ubuntu 18.04系统上成功安装并配置了Eclipse IDE,它将与JDK 8兼容,可以开始进行Java开发工作。如果遇到任何问题,请确保每一步骤都正确执行,并检查是否所有路径都与您的具体情况相匹配。
295 11

热门文章

最新文章