多线程工具类ThreadPoolExecutor

当然你可以编写自己的线程连接池来控制线程,但是java在1.5里已经提供了一个java.util.concurrent.ThreadPoolExecutor的类,这个类已经基本
实现了线程池的功能。
public class TaskExecutorPool {
public static ThreadPoolExecutor taskPool;

static{
taskPool=
new ThreadPoolExecutor(1, 10, 5, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(50),
new ThreadPoolExecutor.CallerRunsPolicy());
}
}
比如有public class TestThread extends Thread
可以通过TaskExecutorPool.taskPool.execute(new TestThread ())
通过构造函数来控制线程池


public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)用给定的初始参数创建新的 ThreadPoolExecutor。

参数:
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
threadFactory - 执行程序创建新线程时使用的工厂。
handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
抛出:
IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小于 0,或者 maximumPoolSize 小于等于 0,或者 corePoolSize 大于 maximumPoolSize。
NullPointerException - 如果 workQueue、threadFactory 或 handler 为 null。

PS:值得注意的几个地方就是maximumPoolSize 设置符合需求,预估出最大可能存在的阻塞队列 写到ArrayBlockingQueue<Runnable>的参数里
### Java多线程工具类 `ThreadPoolExecutor` 和 `ForkJoinPool` #### 什么是 `ThreadPoolExecutor` `ThreadPoolExecutor` 是 Java 中用于管理和调度线程的一个核心类,它是 `ExecutorService` 接口的主要实现之一。该类允许开发者自定义线程池的行为,例如设置核心线程数、最大线程数以及任务队列策略等[^3]。 以下是 `ThreadPoolExecutor` 的主要参数: - **corePoolSize**: 线程池中的最小线程数量。 - **maximumPoolSize**: 线程池能够容纳的最大线程数量。 - **keepAliveTime**: 当前活动线程超过 corePoolSize 时,多余的空闲线程存活的时间。 - **unit**: keepAliveTime 参数的时间单位。 - **workQueue**: 存放待执行任务的阻塞队列。 - **threadFactory**: 创建新线程的工厂。 - **handler**: 配置拒绝策略,在无法处理新任务时采取的操作。 下面是一个简单的 `ThreadPoolExecutor` 使用示例: ```java import java.util.concurrent.*; public class ThreadPoolExecutorExample { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // 核心线程数 4, // 最大线程数 10L, // 超过核心线程数的空闲时间 TimeUnit.SECONDS, // 时间单位 new LinkedBlockingQueue<Runnable>() // 任务队列 ); for (int i = 0; i < 10; i++) { int taskNumber = i; executor.execute(() -> System.out.println("Task " + taskNumber)); } executor.shutdown(); } } ``` --- #### 什么是 `ForkJoinPool` `ForkJoinPool` 是一种专门设计用来支持分治算法(Divide and Conquer Algorithm)的线程池。它的特点是工作窃取机制(Work Stealing),即当某个线程完成自己的任务后,可以去其他线程的任务队列中“偷取”任务并执行[^1]。 `ForkJoinPool` 主要适用于那些可以通过分解成更小子问题解决的大规模计算密集型任务。其典型应用场景包括递归任务拆解和大规模数据集的并行处理。 下面是 `ForkJoinPool` 的基本使用方式: ```java import java.util.concurrent.RecursiveTask; class SumTask extends RecursiveTask<Integer> { private final int[] numbers; private final int start; private final int end; public SumTask(int[] nums, int s, int e) { this.numbers = nums; this.start = s; this.end = e; } @Override protected Integer compute() { if (end - start <= 10) { // 小于阈值直接求和 int sum = 0; for (int i = start; i < end; i++) { sum += numbers[i]; } return sum; } else { int mid = (start + end) / 2; SumTask leftTask = new SumTask(numbers, start, mid); SumTask rightTask = new SumTask(numbers, mid, end); invokeAll(leftTask, rightTask); // 并发执行子任务 return leftTask.join() + rightTask.join(); // 合并结果 } } } public class ForkJoinPoolExample { public static void main(String[] args) throws InterruptedException { int[] data = new int[10_000]; // 初始化数组 for (int i = 0; i < data.length; i++) { data[i] = i; } ForkJoinPool pool = new ForkJoinPool(8); // 设置并发度为8 SumTask task = new SumTask(data, 0, data.length); long startTime = System.currentTimeMillis(); int result = pool.invoke(task); // 执行任务 long endTime = System.currentTimeMillis(); System.out.println("Sum: " + result); System.out.println("Execution Time: " + (endTime - startTime) + " ms"); } } ``` 上述代码展示了如何利用 `ForkJoinPool` 来高效地对大型数组进行并行求和操作。 --- #### 关键区别对比 | 特性 | `ThreadPoolExecutor` | `ForkJoinPool` | |-----------------------|---------------------------------------------|--------------------------------------------| | 设计目标 | 常规任务调度 | 计算密集型任务 | | 工作模式 | 提交任务到共享队列 | 支持 Work Stealing | | 实现基础 | 继承自 AbstractExecutorService | 继承自 AbstractExecutorService | | 拒绝策略 | 可配置 | 默认抛出异常 | --- ### 结论 对于常规任务调度场景,推荐优先考虑基于 `ThreadPoolExecutor` 构建的线程池;而对于复杂的分治算法或者需要充分利用 CPU 并行能力的情况,则更适合采用 `ForkJoinPool`[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值