死锁(任务互相等待)
文章目录
- 死锁(任务互相等待)
- 问题描述
- 错误实现
- 正确实现
死锁(任务互相等待)
问题描述
任务向同一线程池提交子任务并等待其完成,导致线程池资源耗尽,形成死锁。
错误实现
- 线程池饱和:父任务占用唯一线程,子任务进入队列等待。
- 互相等待:父任务等待子任务完成,子任务因队列满无法执行。
public class DeadlockDemo {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, 1, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>()
);
// 提交父任务
executor.execute(() -> {
System.out.println("父任务开始");
Future<?> future = executor.submit(() -> {
System.out.println("子任务开始");
return "子任务结果";
});
try {
future.get(); // 等待子任务完成(但线程池已满,子任务无法执行)
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("父任务结束");
});
}
}
运行结果
父任务开始
(程序挂起,无后续输出)
正确实现
- 解耦任务依赖:避免同一线程池内任务相互等待。
- 使用独立线程池:父子任务由不同线程池处理。
public class DeadlockFixedDemo {
public static void main(String[] args) {
ThreadPoolExecutor parentExecutor =
new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
ThreadPoolExecutor childExecutor =
new ThreadPoolExecutor(2, 2, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// 提交父任务并获取Future
Future<?> parentFuture = parentExecutor.submit(() -> {
System.out.println("父任务开始");
Future<?> childFuture = childExecutor.submit(() -> {
System.out.println("子任务开始");
return "子任务结果";
});
try {
childFuture.get(); // 等待子任务完成
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("父任务结束");
});
try {
// 等待父任务完成
parentFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
// 父任务完成后关闭线程池
parentExecutor.shutdown();
childExecutor.shutdown();
}
}
}
运行结果
父任务开始
子任务开始
父任务结束