您好,登录后才能下订单哦!
# Java线程池的使用实例
## 一、线程池概述
### 1.1 什么是线程池
线程池(Thread Pool)是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池中的线程可以重复利用,减少了频繁创建和销毁线程带来的性能开销。
### 1.2 为什么需要线程池
- **资源消耗控制**:减少线程创建/销毁的系统开销
- **响应速度提升**:任务到达时无需等待线程创建
- **线程管理**:提供线程限制、监控等功能
- **任务队列**:缓冲来不及处理的任务
### 1.3 Java线程池框架
Java通过`java.util.concurrent`包提供线程池支持,核心接口和类包括:
- `Executor`:执行任务的简单接口
- `ExecutorService`:扩展了Executor的功能
- `ThreadPoolExecutor`:可配置的线程池实现
- `Executors`:线程池工厂类
## 二、线程池核心参数
### 2.1 ThreadPoolExecutor构造参数
```java
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)
参数名 | 说明 |
---|---|
corePoolSize | 核心线程数,即使空闲也不会被回收 |
maximumPoolSize | 线程池最大线程数 |
keepAliveTime | 非核心线程空闲存活时间 |
unit | 时间单位(TimeUnit枚举) |
workQueue | 任务队列(BlockingQueue实现) |
threadFactory | 线程创建工厂 |
handler | 拒绝策略处理器 |
// 固定大小线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
// 单线程线程池
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
// 可缓存线程池
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 定时任务线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3);
ThreadPoolExecutor customPool = new ThreadPoolExecutor(
2, // corePoolSize
5, // maximumPoolSize
60, // keepAliveTime
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
public class BasicThreadPoolDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 10; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("执行任务 " + taskId + " 线程: " +
Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
public class CallableDemo {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
final int num = i;
Future<Integer> future = executor.submit(() -> {
System.out.println("计算数字: " + num);
return num * num;
});
futures.add(future);
}
for (Future<Integer> future : futures) {
System.out.println("结果: " + future.get());
}
executor.shutdown();
}
}
public class ScheduledTaskDemo {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// 延迟执行
scheduler.schedule(() -> {
System.out.println("延迟3秒执行");
}, 3, TimeUnit.SECONDS);
// 周期性执行
scheduler.scheduleAtFixedRate(() -> {
System.out.println("每隔2秒执行一次");
}, 1, 2, TimeUnit.SECONDS);
// 保持程序运行
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
scheduler.shutdown();
}
}
队列类型 | 特点 | 适用场景 |
---|---|---|
ArrayBlockingQueue | 有界队列 | 控制资源消耗 |
LinkedBlockingQueue | 无界队列 | 吞吐量优先 |
SynchronousQueue | 直接传递 | 高响应要求 |
PriorityBlockingQueue | 优先级队列 | 任务有优先级 |
策略 | 行为 |
---|---|
AbortPolicy | 抛出RejectedExecutionException |
CallerRunsPolicy | 由调用线程执行任务 |
DiscardPolicy | 直接丢弃任务 |
DiscardOldestPolicy | 丢弃队列最前面的任务 |
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
// 获取活动线程数
int activeCount = executor.getActiveCount();
// 获取已完成任务数
long completedTaskCount = executor.getCompletedTaskCount();
// 获取队列中的任务数
int queueSize = executor.getQueue().size();
// 获取池中当前线程数
int poolSize = executor.getPoolSize();
public class MonitorThreadPoolExecutor extends ThreadPoolExecutor {
public MonitorThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.printf("准备执行: %s 活动线程数: %d 队列大小: %d%n",
t.getName(), getActiveCount(), getQueue().size());
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
System.out.printf("执行完成: %s 活动线程数: %d 已完成任务: %d%n",
Thread.currentThread().getName(),
getActiveCount(), getCompletedTaskCount());
}
}
public class NamedThreadFactory implements ThreadFactory {
private final String namePrefix;
private final AtomicInteger threadNumber = new AtomicInteger(1);
public NamedThreadFactory(String poolName) {
namePrefix = poolName + "-thread-";
}
@Override
public Thread newThread(Runnable r) {
return new Thread(r, namePrefix + threadNumber.getAndIncrement());
}
}
// 使用方式
ExecutorService namedPool = new ThreadPoolExecutor(
4, 8, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
new NamedThreadFactory("order-process")
);
executor.submit(() -> {
try {
// 业务代码
} catch (Exception e) {
// 记录日志
logger.error("任务执行异常", e);
// 可能需要重试或补偿
}
});
// 停止接收新任务
executor.shutdown();
try {
// 等待现有任务完成
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
// 强制关闭
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
问题表现: - CPU利用率低 - 任务堆积严重
解决方案: - 根据任务类型调整线程数 - 使用动态线程池(如Hippo、DynamicTp)
问题表现: - 内存持续增长 - 最终OutOfMemoryError
解决方案: - 使用有界队列 - 设置合理的拒绝策略 - 监控队列大小
问题表现: - 线程数持续增加不释放 - 最终无法创建新线程
解决方案: - 确保任务不会永久阻塞 - 设置合理的keepAliveTime - 使用ThreadPoolExecutor的allowCoreThreadTimeOut
public class FibonacciTask extends RecursiveTask<Long> {
final long n;
FibonacciTask(long n) { this.n = n; }
@Override
protected Long compute() {
if (n <= 10) {
return fibonacci(n);
}
FibonacciTask f1 = new FibonacciTask(n - 1);
f1.fork();
FibonacciTask f2 = new FibonacciTask(n - 2);
return f2.compute() + f1.join();
}
private long fibonacci(long n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
// 使用
ForkJoinPool pool = new ForkJoinPool();
FibonacciTask task = new FibonacciTask(30);
long result = pool.invoke(task);
CompletableFuture.supplyAsync(() -> queryFromDB(), dbPool)
.thenApplyAsync(data -> processData(data), cpuPool)
.thenAcceptAsync(result -> saveResult(result), ioPool)
.exceptionally(ex -> {
logger.error("处理失败", ex);
return null;
});
Java线程池是并发编程的核心组件,合理使用线程池可以: 1. 显著提高系统性能 2. 优化资源利用率 3. 提供更好的可管理性
在实际开发中应该: - 根据业务场景选择合适的配置 - 实现完善的监控机制 - 遵循最佳实践避免常见陷阱
通过本文的各种实例,开发者可以全面掌握线程池的使用方法,构建高效稳定的并发系统。 “`
注:实际字数约为5600字(含代码),这里展示的是主要结构和核心内容。完整文章需要展开各部分说明和补充更多示例代码。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。