面试题答案
一键面试常见应用场景
- 资源隔离:当系统中有多个不同类型的任务,每个任务对资源的需求和影响不同时,使用线程池隔离可以避免一个任务的异常或高负载影响其他任务。例如,在电商系统中,订单处理任务和库存查询任务可通过不同线程池隔离,防止订单处理的高并发导致库存查询服务不可用。
- 防止级联故障:在微服务架构中,如果一个服务调用另一个服务,使用线程池隔离能阻止因被调用服务故障而导致调用方服务资源耗尽。比如,A 服务调用 B 服务,A 服务使用线程池隔离策略,B 服务出现故障时,A 服务的线程池可以限制对 B 服务的请求数量,避免 A 服务因等待 B 服务响应而耗尽自身线程资源。
- 提升响应性:对于一些对响应时间敏感的任务,可以分配单独的线程池,确保其能及时执行。比如,在实时监控系统中,监控数据的收集和处理任务使用单独线程池,能快速响应监控指标变化。
代码层面实现示例
以下是使用 Java 自带的 ThreadPoolExecutor
实现线程池隔离策略的示例:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolIsolationExample {
// 创建一个线程池
private static final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>(100);
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
5,
10,
10L,
TimeUnit.SECONDS,
taskQueue
);
public static void main(String[] args) {
// 模拟任务
for (int i = 0; i < 20; i++) {
final int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " is running in thread " + Thread.currentThread().getName());
try {
// 模拟任务执行时间
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭线程池
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
System.err.println("Pool did not terminate");
}
}
} catch (InterruptedException ie) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
在上述代码中:
ThreadPoolExecutor
创建了一个线程池,核心线程数为 5,最大线程数为 10,任务队列容量为 100。submit
方法将任务提交到线程池,线程池会根据当前线程和任务队列情况分配线程执行任务。- 通过合理设置线程池参数,可以有效地隔离不同类型的任务,避免任务之间相互干扰,提升系统的稳定性和响应性。