面试题答案
一键面试错误处理策略
- 资源竞争
- 使用锁机制:在可能出现资源竞争的代码块(例如共享资源的读写操作)周围使用
synchronized
关键字或者java.util.concurrent.locks.Lock
接口。例如,假设存在一个共享资源sharedResource
:
private static final Object lock = new Object(); private static int sharedResource = 0; // 同步流中的操作 Stream.of(1, 2, 3).forEach(num -> { synchronized (lock) { sharedResource += num; } });
- 线程安全的数据结构:使用线程安全的数据结构,如
ConcurrentHashMap
,CopyOnWriteArrayList
等。例如,在异步流中需要使用一个集合来存储中间结果:
ConcurrentHashMap<Integer, String> resultMap = new ConcurrentHashMap<>(); CompletableFuture.supplyAsync(() -> { // 假设这里是异步流的复杂计算 resultMap.put(1, "result1"); return resultMap; });
- 使用锁机制:在可能出现资源竞争的代码块(例如共享资源的读写操作)周围使用
- 线程池饱和
- 自定义线程池:创建自定义的
ThreadPoolExecutor
,并合理设置核心线程数、最大线程数、队列容量等参数。同时,为线程池设置饱和策略。例如:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 10, // 核心线程数 20, // 最大线程数 1, // 线程存活时间 TimeUnit.MINUTES, new ArrayBlockingQueue<>(50), // 队列容量 new ThreadPoolExecutor.CallerRunsPolicy()); // 饱和策略 CompletableFuture.supplyAsync(() -> { // 异步流中的复杂计算 return "result"; }, executor);
- 监控与调整:通过
ThreadPoolExecutor
的一些方法(如getActiveCount
,getQueue().size()
等)来监控线程池的运行状态,根据实际情况动态调整线程池参数。
- 自定义线程池:创建自定义的
性能优化
- 合理分配同步与异步操作:将耗时较长的复杂计算放在异步流中,而简单的数据过滤等操作放在同步流中。例如:
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5); List<Integer> filteredData = data.stream() .filter(num -> num % 2 == 0) // 同步数据过滤 .collect(Collectors.toList()); CompletableFuture<List<Double>> asyncResult = CompletableFuture.supplyAsync(() -> filteredData.stream() .map(num -> Math.sqrt(num)) // 异步复杂计算 .collect(Collectors.toList()));
- 减少数据转换开销:尽量避免在同步流和异步流之间频繁进行数据结构的转换。如果必须转换,选择高效的转换方式。例如,使用
flatMap
等方法可以避免中间数据结构的创建。 - 复用线程池:在异步操作中复用同一个线程池,而不是每次都创建新的线程池,以减少线程创建和销毁的开销。
关键代码示例
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
public class SyncAsyncStreamExample {
private static final Object lock = new Object();
private static int sharedResource = 0;
public static void main(String[] args) {
// 自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10,
20,
1,
TimeUnit.MINUTES,
new ArrayBlockingQueue<>(50),
new ThreadPoolExecutor.CallerRunsPolicy());
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
// 同步数据过滤
List<Integer> filteredData = data.stream()
.filter(num -> num % 2 == 0)
.collect(Collectors.toList());
// 异步复杂计算
CompletableFuture<List<Double>> asyncResult = CompletableFuture.supplyAsync(() ->
filteredData.stream()
.map(num -> Math.sqrt(num))
.collect(Collectors.toList()), executor);
asyncResult.thenAccept(result -> {
synchronized (lock) {
sharedResource += result.size();
}
});
executor.shutdown();
}
}
上述代码展示了如何在同步和异步流混合的场景下进行错误处理和性能优化。通过锁机制处理资源竞争,自定义线程池及饱和策略处理线程池饱和问题,并合理分配同步与异步操作来优化性能。