面试题答案
一键面试负载衡量指标选择
选择CPU使用率作为负载衡量指标。因为CPU使用率能够直观反映系统当前处理任务的繁忙程度,较高的CPU使用率通常意味着系统负载较高,需要更多线程来处理任务;较低的CPU使用率则表示系统负载较低,可以适当减少线程数量以节省资源。
关键代码片段
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class AIOThreadPoolDynamicAdjustment {
private static final int CORE_POOL_SIZE = 5;
private static final int MAX_POOL_SIZE = 50;
private static final long KEEP_ALIVE_TIME = 10L;
private static final ExecutorService executorService = Executors.newFixedThreadPool(CORE_POOL_SIZE);
private static final OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
public static void main(String[] args) {
Thread monitorThread = new Thread(() -> {
while (true) {
double cpuUsage = getSystemCpuUsage();
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
if (cpuUsage > 0.7) {
if (threadPoolExecutor.getPoolSize() < MAX_POOL_SIZE) {
threadPoolExecutor.setCorePoolSize(threadPoolExecutor.getCorePoolSize() + 1);
threadPoolExecutor.setMaximumPoolSize(threadPoolExecutor.getMaximumPoolSize() + 1);
}
} else if (cpuUsage < 0.3 && threadPoolExecutor.getPoolSize() > CORE_POOL_SIZE) {
threadPoolExecutor.setCorePoolSize(threadPoolExecutor.getCorePoolSize() - 1);
threadPoolExecutor.setMaximumPoolSize(threadPoolExecutor.getMaximumPoolSize() - 1);
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
monitorThread.setDaemon(true);
monitorThread.start();
// 模拟任务提交
for (int i = 0; i < 100; i++) {
executorService.submit(() -> {
// 模拟任务执行
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
private static double getSystemCpuUsage() {
try {
Method method = osBean.getClass().getMethod("getSystemCpuLoad");
method.setAccessible(true);
Double cpuUsage = (Double) method.invoke(osBean);
if (cpuUsage == -1.0) {
return 0.0;
}
return cpuUsage;
} catch (Exception e) {
e.printStackTrace();
return 0.0;
}
}
}
代码工作原理
- 获取CPU使用率:
getSystemCpuUsage
方法通过反射调用OperatingSystemMXBean
的getSystemCpuLoad
方法获取系统CPU使用率。该方法返回值范围为0.0到1.0,代表CPU使用率的百分比。 - 线程池监控与调整:在
main
方法中启动一个守护线程monitorThread
,该线程每隔5秒检查一次系统CPU使用率。- 如果CPU使用率大于70% (
cpuUsage > 0.7
),并且当前线程池大小小于最大线程池大小 (threadPoolExecutor.getPoolSize() < MAX_POOL_SIZE
),则增加线程池的核心线程数和最大线程数各1。 - 如果CPU使用率小于30% (
cpuUsage < 0.3
),并且当前线程池大小大于核心线程数 (threadPoolExecutor.getPoolSize() > CORE_POOL_SIZE
),则减少线程池的核心线程数和最大线程数各1。
- 如果CPU使用率大于70% (
- 线程池初始化:使用
Executors.newFixedThreadPool(CORE_POOL_SIZE)
初始化一个固定大小的线程池,初始核心线程数为CORE_POOL_SIZE
。在实际应用中,可以根据具体需求调整CORE_POOL_SIZE
和MAX_POOL_SIZE
等参数。 - 任务提交:通过
executorService.submit
方法模拟向线程池提交任务,任务模拟执行1秒。
通过这种方式实现了AIO异步线程池大小根据系统CPU使用率动态调整的策略。