线程池工具类:简化并发编程,提升任务执行效率
在多线程编程中,线程池是一种重要的资源管理工具。它可以有效地管理线程的生命周期,避免频繁创建和销毁线程带来的性能开销,同时还能控制并发任务的执行顺序和资源占用。为了简化线程池的使用,我们可以封装一个通用的线程池工具类,提供便捷的任务提交、线程池配置和监控功能。
线程池工具类的设计目标
-
简化线程池的创建和管理:
- 提供默认的线程池配置,同时支持自定义配置。
- 封装线程池的创建逻辑,避免重复代码。
-
支持多种任务提交方式:
- 支持提交
Runnable
和Callable
任务。 - 支持获取任务的执行结果(
Future
)。
- 支持提交
-
提供线程池监控功能:
- 实时获取线程池的状态(如活跃线程数、任务队列大小等)。
- 支持关闭线程池并等待任务完成。
-
异常处理:
- 捕获任务执行中的异常,避免线程池因异常而崩溃。
线程池工具类的实现
以下是一个完整的线程池工具类实现:
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 线程池工具类
*/
public class ThreadPoolUtil {
// 默认线程池配置
private static final int DEFAULT_CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors(); // 核心线程数
private static final int DEFAULT_MAX_POOL_SIZE = DEFAULT_CORE_POOL_SIZE * 2; // 最大线程数
private static final int DEFAULT_QUEUE_CAPACITY = 100; // 任务队列容量
private static final long DEFAULT_KEEP_ALIVE_TIME = 60L; // 线程空闲时间(秒)
// 线程池实例
private static volatile ThreadPoolExecutor threadPool;
// 线程工厂(用于自定义线程名称)
private static final ThreadFactory threadFactory = new ThreadFactory() {
private final AtomicInteger threadNumber = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "pool-thread-" + threadNumber.getAndIncrement());
}
};
// 私有构造方法,禁止外部实例化
private ThreadPoolUtil() {
}
/**
* 获取线程池实例(单例模式)
*
* @return 线程池实例
*/
public static ThreadPoolExecutor getThreadPool() {
if (threadPool == null) {
synchronized (ThreadPoolUtil.class) {
if (threadPool == null) {
threadPool = new ThreadPoolExecutor(
DEFAULT_CORE_POOL_SIZE,
DEFAULT_MAX_POOL_SIZE,
DEFAULT_KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(DEFAULT_QUEUE_CAPACITY),
threadFactory,
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略:直接抛出异常
);
}
}
}
return threadPool;
}
/**
* 提交任务(Runnable)
*
* @param task 任务
*/
public static void execute(Runnable task) {
getThreadPool().execute(task);
}
/**
* 提交任务(Callable)
*
* @param task 任务
* @param <T> 返回值类型
* @return Future 对象
*/
public static <T> Future<T> submit(Callable<T> task) {
return getThreadPool().submit(task);
}
/**
* 关闭线程池(等待所有任务完成)
*/
public static void shutdown() {
if (threadPool != null) {
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
threadPool.shutdownNow();
}
} catch (InterruptedException e) {
threadPool.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
/**
* 立即关闭线程池(不等待任务完成)
*/
public static void shutdownNow() {
if (threadPool != null) {
threadPool.shutdownNow();
}
}
/**
* 获取线程池状态
*
* @return 线程池状态信息
*/
public static String getThreadPoolStatus() {
if (threadPool == null) {
return "Thread pool is not initialized.";
}
return String.format(
"Pool Status: [CorePoolSize: %d, ActiveThreads: %d, CompletedTasks: %d, QueueSize: %d]",
threadPool.getCorePoolSize(),
threadPool.getActiveCount(),
threadPool.getCompletedTaskCount(),
threadPool.getQueue().size()
);
}
}
工具类的使用示例
1. 提交任务
public class ThreadPoolExample {
public static void main(String[] args) {
// 提交 Runnable 任务
ThreadPoolUtil.execute(() -> {
System.out.println("Runnable task is running.");
});
// 提交 Callable 任务并获取结果
Future<String> future = ThreadPoolUtil.submit(() -> {
Thread.sleep(1000);
return "Callable task result";
});
try {
System.out.println("Callable task result: " + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 打印线程池状态
System.out.println(ThreadPoolUtil.getThreadPoolStatus());
// 关闭线程池
ThreadPoolUtil.shutdown();
}
}
2. 监控线程池状态
System.out.println(ThreadPoolUtil.getThreadPoolStatus());
3. 关闭线程池
// 等待所有任务完成
ThreadPoolUtil.shutdown();
// 立即关闭线程池
ThreadPoolUtil.shutdownNow();
工具类的核心功能
-
线程池的单例模式:
- 通过双重检查锁定(Double-Checked Locking)确保线程池的单例性。
-
自定义线程工厂:
- 为线程池中的线程设置自定义名称,方便调试和监控。
-
任务提交:
- 支持
Runnable
和Callable
任务的提交,并返回Future
对象以获取任务结果。
- 支持
-
线程池关闭:
- 提供两种关闭方式:
shutdown
(等待任务完成)和shutdownNow
(立即关闭)。
- 提供两种关闭方式:
-
线程池状态监控:
- 实时获取线程池的核心线程数、活跃线程数、已完成任务数和任务队列大小。
总结
通过封装线程池工具类,我们可以简化多线程编程的复杂性,提升代码的可维护性和可读性。该工具类不仅提供了默认的线程池配置,还支持任务提交、线程池监控和关闭等功能,能够满足大多数并发编程的需求。在实际项目中,可以根据具体场景进一步扩展和优化该工具类。