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

用代码示例说明如何通过线程池实现Java多线程编程

在Java中,线程池是管理多线程的高效方式,它通过复用线程减少频繁创建/销毁线程的开销。以下通过代码示例详细说明如何使用线程池实现多线程编程,包括线程池的创建、提交任务、获取结果及关闭线程池等核心操作。

一、线程池核心API简介

Java通过java.util.concurrent包提供线程池支持,核心类和接口:

  • ExecutorService:线程池核心接口,定义了提交任务、关闭线程池等方法。
  • Executors:工具类,提供快速创建常见线程池的静态方法(实际开发中推荐ThreadPoolExecutor自定义线程池,更灵活)。
  • ThreadPoolExecutor:线程池的核心实现类,可自定义核心线程数、最大线程数等参数。

二、线程池使用步骤(代码示例)

1. 基本使用:提交Runnable任务(无返回值)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolRunnableDemo {public static void main(String[] args) {// 1. 创建线程池(这里用Executors.newFixedThreadPool创建固定大小的线程池)// 核心线程数为3,即同时最多运行3个线程ExecutorService executor = Executors.newFixedThreadPool(3);// 2. 提交任务(Runnable接口,无返回值)for (int i = 0; i < 5; i++) { // 提交5个任务final int taskId = i; // 任务编号// 提交Runnable任务executor.submit(new Runnable() {@Overridepublic void run() {// 任务逻辑:打印线程名和任务ID,模拟耗时操作System.out.println("线程" + Thread.currentThread().getName() + " 执行任务" + taskId);try {Thread.sleep(1000); // 模拟任务耗时1秒} catch (InterruptedException e) {e.printStackTrace();}}});}// 3. 关闭线程池(重要!否则程序会一直运行)// shutdown():不再接受新任务,等待已有任务执行完毕后关闭executor.shutdown();}
}

输出说明
线程池有3个核心线程,5个任务会分两批执行(前3个同时执行,1秒后执行剩余2个),输出类似:

线程pool-1-thread-1 执行任务0
线程pool-1-thread-2 执行任务1
线程pool-1-thread-3 执行任务2
(1秒后)
线程pool-1-thread-1 执行任务3
线程pool-1-thread-2 执行任务4
2. 提交Callable任务(有返回值)

如果需要线程返回结果,可提交Callable任务,通过Future获取结果。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class ThreadPoolCallableDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {// 1. 创建线程池(单线程池,仅1个线程)ExecutorService executor = Executors.newSingleThreadExecutor();// 2. 提交Callable任务(有返回值,这里返回1~n的和)Callable<Integer> task = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 1; i <= 100; i++) {sum += i;}return sum; // 返回计算结果}};// 提交任务并获取Future对象(用于获取结果)Future<Integer> future = executor.submit(task);// 3. 关闭线程池executor.shutdown();// 4. 通过Future获取结果(get()会阻塞,直到任务完成)int result = future.get();System.out.println("1~100的和:" + result); // 输出:5050}
}

多任务批量获取结果示例

public class ThreadPoolMultiCallableDemo {public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建固定大小为2的线程池ExecutorService executor = Executors.newFixedThreadPool(2);// 存储多个Future对象List<Future<Integer>> futures = new ArrayList<>();// 提交3个任务(计算1~n的和)for (int i = 1; i <= 3; i++) {final int num = i * 100; // 分别计算1~100、1~200、1~300的和Future<Integer> future = executor.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int j = 1; j <= num; j++) {sum += j;}return sum;}});futures.add(future);}// 关闭线程池executor.shutdown();// 遍历Future获取所有结果for (int i = 0; i < futures.size(); i++) {System.out.println("1~" + (i + 1) * 100 + "的和:" + futures.get(i).get());}}
}

输出

1~100的和:5050
1~200的和:20100
1~300的和:45150
3. 自定义线程池(ThreadPoolExecutor

Executors创建的线程池有潜在风险(如newCachedThreadPool可能创建大量线程导致OOM),实际开发中推荐用ThreadPoolExecutor自定义参数:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class CustomThreadPoolDemo {public static void main(String[] args) {// 自定义线程池参数int corePoolSize = 2; // 核心线程数(常驻线程)int maximumPoolSize = 4; // 最大线程数(核心线程+临时线程)long keepAliveTime = 60; // 临时线程空闲时间TimeUnit unit = TimeUnit.SECONDS; // 时间单位// 任务队列(容量为2,超出的任务会创建临时线程)ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);// 创建自定义线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue);// 提交5个任务for (int i = 0; i < 5; i++) {final int taskId = i;executor.submit(new Runnable() {@Overridepublic void run() {System.out.println("线程" + Thread.currentThread().getName() + " 执行任务" + taskId);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});}// 关闭线程池executor.shutdown();}
}

参数说明

  • 核心线程数2,任务队列容量2。提交5个任务时:
    • 前2个任务由核心线程执行;
    • 中间2个任务放入队列等待;
    • 第5个任务触发创建临时线程(最大线程数4,因此可创建2个临时线程)。

三、线程池常用方法

方法说明
submit(Runnable)提交无返回值的任务,返回Future<?>
submit(Callable<T>)提交有返回值的任务,返回Future<T>
shutdown()平缓关闭:不再接受新任务,等待现有任务完成后关闭
shutdownNow()强制关闭:尝试中断所有任务,返回未执行的任务
isShutdown()判断线程池是否已关闭
isTerminated()判断所有任务是否执行完毕

四、线程池优势总结

  1. 复用线程:减少线程创建/销毁的资源消耗。
  2. 控制并发数:避免线程过多导致的系统资源耗尽。
  3. 管理任务队列:有序执行任务,避免任务丢失。
  4. 提高响应速度:核心线程常驻,无需等待线程创建即可执行任务。

通过线程池实现多线程编程是工业级开发的最佳实践,需根据业务场景合理选择线程池类型和参数。

http://www.dtcms.com/a/569530.html

相关文章:

  • 网易做网站企业怎么在网站上做宣传
  • 响应式网站制作工具搜了网
  • [Android] 人事考试网v1.0.4
  • Python 面向对象
  • 技术解析:佐航BYQ3313S手持式三相直阻测试仪如何重塑多场景变压器检测价值
  • RuoyiApp 在vuex,state存储nickname vue2
  • 常见的网站类型有哪些wordpress收费会员
  • 建设银行成都开发中心网站saas云建站
  • 视频网站如何做爱奇艺做任务领vip网站
  • 用python可视化分析上海教育中考新政
  • MySQL的UPPER函数介绍
  • 自己搭建一个网站我做钓鱼网站自首了
  • 专用主机方式建设网站用discuz做的大网站
  • [特殊字符] Java/Vue 实现体育比分直播系统,支持多端实时更新
  • 沈阳哪个网站建设公司好重庆网站制作一般多少钱
  • 用vscode连接远端ubuntu无法git push,vscode无法连接centos
  • 商业门户网站怎么运营淘宝关键词怎么选取
  • oj 素数个数 难
  • 全球前10网站开发语言百度做网站需要多少钱
  • Affinity三大专业工具整合免费开放
  • ZSAR配置PDUR模块
  • 基于springboot的校园社团信息管理系统开发与设计
  • 鹿寨县住房和城乡建设局网站网站改版 英文
  • 为什么Redis的操作是原子性的?如何保证原子性的?
  • C++17 异构(tuple)与多模态数据结构(variant)
  • 【SpringBoot】玩转 Spring Boot 日志:级别划分、持久化、格式配置及 Lombok 简化使用
  • 火山引擎数智平台VeDI重磅发布“AI助手”:以大模型驱动数据飞轮,赋能非技术人员高效“看数、用数”
  • 前言:可视化搭建诞生背景 什么是可视化
  • 个人博客网站怎么注册网站怎么做会员系统
  • 山东省建设厅招标网站首页c可以做网站吗