多线程是 Java 中非常重要的技术,合理使用线程池可以有效提升系统性能、控制资源消耗。下面整理了一个 通用线程池工具类,并逐行解释每个参数和使用方法
1️⃣ 工具类代码
package org.berlin.shirotest.common.utils;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
/**
* 通用线程池工具类
*/
@Slf4j
public class ThreadPoolUtils {
// CPU 核心数
private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
// 最大线程数
private static final int MAX_POOL_SIZE = CORE_POOL_SIZE * 2;
// 非核心线程存活时间(秒)
private static final int KEEP_ALIVE_SECONDS = 60;
// 队列容量
private static final int QUEUE_CAPACITY = 500;
// 创建线程池
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_SECONDS,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(QUEUE_CAPACITY), // 阻塞队列
new ThreadFactory() { // 自定义线程工厂
private final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
private int counter = 0;
@Override
public Thread newThread(Runnable r) {
Thread t = defaultFactory.newThread(r);
t.setName("custom-pool-thread-" + (++counter));
t.setDaemon(false); // 非守护线程
return t;
}
},
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
static {
// 定时打印线程池状态(可选)
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
log.info("ThreadPool ActiveCount={}, QueueSize={}, CompletedTaskCount={}",
executor.getActiveCount(),
executor.getQueue().size(),
executor.getCompletedTaskCount());
}, 0, 30, TimeUnit.SECONDS);
}
private ThreadPoolUtils() {
// 工具类不允许实例化
}
/** 提交 Runnable 任务 */
public static void execute(Runnable task) {
executor.execute(task);
}
/** 提交 Callable 任务,返回 Future */
public static <T> Future<T> submit(Callable<T> task) {
return executor.submit(task);
}
/** 提交 Runnable 任务,带返回 Future */
public static Future<?> submit(Runnable task) {
return executor.submit(task);
}
/** 获取线程池实例 */
public static ThreadPoolExecutor getExecutor() {
return executor;
}
/** 优雅关闭线程池 */
public static void shutdown() {
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
2️⃣ 参数详解
| 参数 | 含义 | 说明 |
|---|---|---|
CORE_POOL_SIZE | 核心线程数 | 核心线程会一直保留,即使空闲 |
MAX_POOL_SIZE | 最大线程数 | 当任务量大于队列容量时,可以扩展到最大线程数 |
KEEP_ALIVE_SECONDS | 非核心线程存活时间 | 空闲线程超过该时间会被回收 |
QUEUE_CAPACITY | 阻塞队列容量 | 存放等待执行的任务 |
ThreadFactory | 线程工厂 | 可以自定义线程名、是否守护线程等 |
CallerRunsPolicy | 拒绝策略 | 当队列满了且线程数达到最大值,任务在调用线程执行 |
LinkedBlockingQueue | 阻塞队列 | 默认 FIFO,保证任务顺序执行 |
拒绝策略说明
-
CallerRunsPolicy:调用线程执行任务
-
AbortPolicy:抛异常
-
DiscardPolicy:丢弃新任务
-
DiscardOldestPolicy:丢弃队列最老任务
3️⃣ 使用示例
① 无返回值任务
ThreadPoolUtils.execute(() -> {
System.out.println("Hello from thread: " + Thread.currentThread().getName());
});
② 带返回值任务
Future<Integer> future = ThreadPoolUtils.submit(() -> {
Thread.sleep(1000);
return 42;
});
System.out.println("Result: " + future.get());
③ 获取线程池实例
ThreadPoolExecutor executor = ThreadPoolUtils.getExecutor();
System.out.println("Active threads: " + executor.getActiveCount());
④ 优雅关闭线程池
ThreadPoolUtils.shutdown();
4️⃣ 使用场景
-
异步任务执行
-
日志记录、消息推送、定时任务等
-
-
高并发场景
-
Web 请求处理、批量数据处理
-
-
资源控制
-
限制线程数、防止系统过载
-
-
统一管理线程
-
所有线程由统一线程池管理,便于监控和调优
-
💡 小技巧
-
核心线程数一般 = CPU 核心数
-
队列长度根据任务量调节,避免过多堆积
-
拒绝策略根据业务需求选择,
CallerRunsPolicy是最安全的默认策略
本篇文章介绍了一个 Java 通用线程池工具类,适合管理异步任务、高并发场景和资源控制。
核心内容
-
工具类特点
-
封装
ThreadPoolExecutor -
支持
Runnable和Callable任务 -
可统一获取线程池实例和优雅关闭
-
自动打印线程池状态(可选)
-
-
主要参数
-
核心线程数:CPU 核心数
-
最大线程数:核心线程数 × 2
-
非核心线程存活时间:60 秒
-
队列容量:500(阻塞队列 FIFO)
-
线程工厂:自定义线程名、守护线程设置
-
拒绝策略:队列满时调用线程执行任务(CallerRunsPolicy)
-
-
使用示例
-
提交无返回值任务:
execute(Runnable) -
提交有返回值任务:
submit(Callable<T>) -
获取线程池实例:
getExecutor() -
优雅关闭线程池:
shutdown()
-
-
应用场景
-
异步日志、消息推送、定时任务
-
高并发 Web 请求、批量数据处理
-
统一线程管理、资源控制和监控
-
💡 阅读提示
-
核心线程数 = CPU 核心数,队列长度根据任务量调整
-
拒绝策略可根据业务需求选择,
CallerRunsPolicy是安全默认 -
线程池可提高性能、降低资源消耗,并便于统一管理
1478

被折叠的 条评论
为什么被折叠?



