Java 并发编程入门:线程池、锁、CompletableFuture
并发编程是 Java 的核心特性。本文介绍并发编程的基础知识。
线程池
创建线程池
// 推荐方式
ExecutorService executor = Executors.newFixedThreadPool(10);
// 自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // 核心线程数
20, // 最大线程数
60, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(100), // 任务队列
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
使用线程池
// 提交任务
executor.execute(() -> System.out.println("执行任务"));
// 提交有返回值的任务
Future<String> future = executor.submit(() -> "结果");
String result = future.get(); // 阻塞等待
线程池参数说明
| 参数 | 说明 |
|---|---|
| corePoolSize | 核心线程数 |
| maximumPoolSize | 最大线程数 |
| keepAliveTime | 空闲线程存活时间 |
| workQueue | 任务队列 |
| threadFactory | 线程工厂 |
| handler | 拒绝策略 |
锁
synchronized
// 同步方法
public synchronized void method() {
// 临界区
}
// 同步块
synchronized (this) {
// 临界区
}
ReentrantLock
private final ReentrantLock lock = new ReentrantLock();
public void method() {
lock.lock();
try {
// 临界区
} finally {
lock.unlock();
}
}
ReadWriteLock
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void read() {
rwLock.readLock().lock();
try {
// 读操作
} finally {
rwLock.readLock().unlock();
}
}
public void write() {
rwLock.writeLock().lock();
try {
// 写操作
} finally {
rwLock.writeLock().unlock();
}
}
CompletableFuture
基本用法
// 异步执行
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "结果";
});
// 链式处理
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World")
.thenApply(String::toUpperCase);
组合多个异步任务
// 等待所有完成
CompletableFuture.allOf(future1, future2, future3).join();
// 任意完成
CompletableFuture.anyOf(future1, future2, future3).join();
异常处理
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
if (true) throw new RuntimeException("错误");
return "结果";
})
.exceptionally(e -> "默认值");
最佳实践
- 使用线程池:避免手动创建线程
- 合理设置线程数:CPU 密集型 = CPU 核心数,IO 密集型 = CPU 核心数 × 2
- 使用 CompletableFuture:比 Future 更强大
- 避免死锁:按固定顺序获取锁
总结
Java 并发编程是高级开发者的必备技能。掌握线程池、锁、CompletableFuture,可以编写高效的并发程序。