ExecutorService 线程池

ExecutorService详解
本文详细介绍了ExecutorService接口及其实现类的功能,包括任务类型、任务执行方式、线程池创建方法及控制线程池的方法等。此外还讲解了如何通过不同的方法控制线程池的关闭。
/**
 * ExecutorServiceAnalyze.java
 */
package com.xxx.common.concurrent;

/**
 * ExecutorService 线程池
 */
public class ExecutorServiceAnalyze {
	
	// ExecutorService接口
	// 实现类有AbstractExecutorService,ScheduledThreadPoolExecutor,ThreadPoolExecutor.
	
	// 任务分两类:一类是实现了Runnable接口的类,一类是实现了Callable接口的类.
	// Runnable任务没有返回值,而Callable任务有返回值.
	// Callable的call()方法只能通过ExecutorService的submit(Callable<T> task)方法来执行,
	// 并且返回一个<T> Future<T>,是表示任务等待完成的Future.
	// Runnable不会返回结果,并且无法抛出经过检查的异常.
	
	// shutdown 平滑地关闭ExecutorService,停止接受任何新的任务且等待已经提交的任务执行完成.
	
	// awaitTermination 使线程等待timeout时长,当超过timeout时间后,会监测ExecutorService是否已经关闭,
	// 若关闭则返回true,否则返回false. 和shutdown方法组合使用.
	
	// shutdownNow 强制关闭ExecutorService,取消所有运行中的任务和在工作队列中等待的任务,
	// 这个方法返回一个List列表,列表中返回的是等待在工作队列中的任务.
	// List<Runnable> runs = service.shutdownNow();
	
	// isTerminated 校验ExecutorService当前的状态是否关闭状态.
	
	// isShutdown 在ExecutorService关闭后返回true,否则返回false.
	
	// execute 将一个实现了Runnable类型的类的实例作为参数传入execute方法并执行.
	
	// submit 提交一个有返回值的任务用于执行,参数为Runnable或Callable.
	
	/**
	 * Application entry point.
	 */
	public static void main(String[] args) {
		
		// 创建一个使用单个 worker 线程的 Executor
		// ExecutorService executorService = Executors.newSingleThreadExecutor();
		
		// 创建一个可重用固定线程数的线程池
		// ExecutorService executorService = Executors.newFixedThreadPool(10);
		
		// 可安排在给定的延迟后运行或定期执行的命令
		// ExecutorService executorService = Executors.newScheduledThreadPool(10);
		
		// 可根据需要创建新线程的线程池
		// ExecutorService executorService = Executors.newCachedThreadPool();
		
	}

}

 

<think> 我们参考用户提供的引用资料,特别是引用[1]和引用[4]中的示例,来构建一个ExecutorService线程池在业务中使用的完整示例。 用户希望看到的是业务中使用的示例,因此我们将模拟一个常见的业务场景:并发处理多个订单任务。 场景描述: 假设我们有一个订单处理系统,需要同时处理多个订单。每个订单的处理包括以下步骤: 1. 验证订单信息 2. 计算订单金额(可能涉及远程调用,这里用睡眠模拟耗时) 3. 保存订单到数据库(模拟) 我们将使用ExecutorService线程池来并发处理这些订单任务,提高处理效率。 注意点: 1. 使用ThreadPoolExecutor创建线程池,并合理配置参数(核心线程数、最大线程数、队列容量等) 2. 使用submit提交Callable任务(因为需要返回处理结果) 3. 获取每个订单处理的结果(Future对象)并处理可能的异常 4. 优雅关闭线程池 示例代码: </think>以下是一个基于业务场景的`ExecutorService`线程池使用完整示例,模拟电商系统中的订单处理流程: ```java import java.util.concurrent.*; import java.util.*; public class OrderProcessingSystem { // 订单处理服务(模拟业务逻辑) static class OrderService { public String processOrder(String orderId) throws InterruptedException { // 模拟业务处理时间(50-150ms) int processTime = 50 + new Random().nextInt(100); Thread.sleep(processTime); // 返回处理结果(实际业务可能包含数据库操作等) return String.format("订单[%s]处理完成 | 耗时:%dms | 线程:%s", orderId, processTime, Thread.currentThread().getName()); } } public static void main(String[] args) throws InterruptedException { // 1. 创建线程池(根据业务需求配置) ThreadPoolExecutor executor = new ThreadPoolExecutor( 4, // 核心线程数(日常负载) 10, // 最大线程数(应对流量高峰) 30, TimeUnit.SECONDS, // 空闲线程存活时间 new LinkedBlockingQueue<>(50), // 任务队列容量 new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略 ); OrderService orderService = new OrderService(); List<Future<String>> futures = new ArrayList<>(); Scanner scanner = new Scanner(System.in); System.out.print("请输入要生成的订单数量: "); int orderCount = scanner.nextInt(); // 2. 提交订单处理任务 for (int i = 1; i <= orderCount; i++) { String orderId = "ORD2023" + String.format("%05d", i); futures.add(executor.submit(() -> { try { return orderService.processOrder(orderId); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return "订单处理被中断: " + orderId; } })); } // 3. 监控线程池状态(业务系统常用) new Thread(() -> { while (!executor.isTerminated()) { System.out.printf("\n[监控] 活动线程: %d | 队列任务: %d | 完成订单: %d", executor.getActiveCount(), executor.getQueue().size(), executor.getCompletedTaskCount()); try { Thread.sleep(2000); } catch (InterruptedException ignored) {} } }).start(); // 4. 获取处理结果 System.out.println("\n\n=== 订单处理结果 ==="); for (Future<String> future : futures) { try { // 设置超时防止阻塞 System.out.println(future.get(500, TimeUnit.MILLISECONDS)); } catch (TimeoutException e) { System.err.println("订单处理超时,转人工处理"); } catch (Exception e) { System.err.println("系统错误: " + e.getCause().getMessage()); } } // 5. 优雅关闭线程池 executor.shutdown(); if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { List<Runnable> unfinished = executor.shutdownNow(); System.err.println("强制关闭,未完成订单: " + unfinished.size()); } System.out.println("=== 所有订单处理完成 ==="); } } ``` ### 业务场景关键点说明: 1. **线程池配置** ```java new ThreadPoolExecutor(4, 10, 30, SECONDS, new LinkedBlockingQueue<>(50), new CallerRunsPolicy()) ``` - 核心线程数4:日常订单处理能力 - 最大线程数10:应对促销高峰流量 - 队列容量50:缓冲突发流量[^1] - 拒绝策略:当系统过载时,由提交线程处理订单(避免丢弃订单) 2. **订单处理流程** ```java executor.submit(() -> orderService.processOrder(orderId)) ``` - 每个订单作为独立任务提交 - 使用Callable返回处理结果 - 异常捕获保证任务稳定性 3. **生产级特性** - **实时监控**:独立线程监控线程池状态 ```java executor.getActiveCount() // 活动线程数 executor.getQueue().size() // 排队任务数 ``` - **超时控制**:防止个别订单阻塞系统 ```java future.get(500, TimeUnit.MILLISECONDS) ``` - **优雅关闭**: ```java executor.shutdown(); // 停止接收新订单 executor.awaitTermination(10, SECONDS); // 等待现有订单完成 executor.shutdownNow(); // 强制终止(最后手段) ``` ### 运行示例: ``` 请输入要生成的订单数量: 15 [监控] 活动线程: 4 | 队列任务: 11 | 完成订单: 0 [监控] 活动线程: 4 | 队列任务: 7 | 完成订单: 4 === 订单处理结果 === 订单[ORD202300001]处理完成 | 耗时:72ms | 线程:pool-1-thread-2 订单[ORD202300002]处理完成 | 耗时:112ms | 线程:pool-1-thread-1 ... 订单[ORD202300015]处理完成 | 耗时:98ms | 线程:pool-1-thread-4 [监控] 活动线程: 0 | 队列任务: 0 | 完成订单: 15 === 所有订单处理完成 === ``` ### 业务实践建议: 1. **参数调优**:根据系统监控调整核心参数 2. **命名线程**:使用`ThreadFactory`命名线程便于排查问题 ```java new ThreadFactoryBuilder().setNameFormat("Order-Thread-%d").build() ``` 3. **异常处理**:添加`UncaughtExceptionHandler`捕获未处理异常 4. **资源隔离**:不同业务使用独立线程池避免相互影响[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值