面试题答案
一键面试1. 使用CountDownLatch协调任务
假设我们有多个子任务,其中一些子任务依赖其他子任务的中间结果。
import java.util.concurrent.CountDownLatch;
public class DistributedTask {
public static void main(String[] args) {
int totalTasks = 5;
CountDownLatch latch = new CountDownLatch(totalTasks);
// 定义依赖其他任务的子任务
Runnable dependentTask = () -> {
try {
// 等待其他任务完成
latch.await();
System.out.println("Dependent task is starting after all dependencies are done.");
// 执行依赖任务的逻辑
} catch (InterruptedException e) {
e.printStackTrace();
}
};
// 定义其他普通子任务
for (int i = 0; i < totalTasks; i++) {
new Thread(() -> {
try {
// 模拟任务执行
Thread.sleep(1000);
System.out.println("Task completed.");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 任务完成,减少计数器
latch.countDown();
}
}).start();
}
new Thread(dependentTask).start();
}
}
2. 使用CyclicBarrier协调任务
import java.util.concurrent.CyclicBarrier;
public class DistributedTaskWithCyclicBarrier {
public static void main(String[] args) {
int totalTasks = 5;
CyclicBarrier barrier = new CyclicBarrier(totalTasks, () -> {
System.out.println("All tasks are at the barrier, starting dependent task.");
// 执行依赖任务的逻辑
});
for (int i = 0; i < totalTasks; i++) {
new Thread(() -> {
try {
// 模拟任务执行
Thread.sleep(1000);
System.out.println("Task completed.");
// 到达屏障
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
3. 高并发场景下性能优化及避免死锁
- 性能优化:
- 减少等待时间:尽量让任务执行时间缩短,比如优化算法、使用更高效的数据结构。如果任务中有I/O操作,可以考虑使用异步I/O。
- 合理设置并行度:根据系统资源(如CPU核心数、内存等)合理设置并行执行的任务数量,避免过多任务竞争资源导致性能下降。
- 避免死锁:
- 顺序执行:确保所有任务按照相同的顺序获取和释放资源。比如在多个任务依赖关系复杂时,给任务编号,依赖关系按编号顺序执行。
- 超时机制:在使用
await
方法时设置超时时间。如latch.await(5, TimeUnit.SECONDS)
,如果等待超过5秒则放弃等待,避免无限期等待。 - 资源分配图算法:在复杂依赖场景下,可以使用资源分配图算法(如死锁检测算法)来动态检测和避免死锁。定期检查系统中任务和资源的依赖关系,发现死锁隐患及时处理。