面试题答案
一键面试任务分类管理
- 按执行时间分类:
- 短任务:执行时间较短(如几十毫秒以内)的任务。这些任务对系统资源的占用时间相对较短,可以批量执行。
- 长任务:执行时间较长(如超过1秒甚至更久)的任务。长任务可能会阻塞线程,影响其他任务的执行,需要单独处理。
- 按资源消耗分类:
- 轻量级任务:对CPU、内存等资源消耗较小的任务。这类任务可以和其他轻量级任务共用线程。
- 重量级任务:对资源消耗较大的任务,例如需要大量内存或长时间占用CPU的任务。这类任务应避免与其他任务竞争资源。
线程池参数优化配置
- 核心线程数(corePoolSize): 根据任务类型和预估的并发量来设置。对于短任务和轻量级任务,可以适当设置较大的核心线程数,以充分利用系统资源。例如,如果预估有大量短任务并发,可以将核心线程数设置为CPU核心数的2 - 3倍。对于长任务和重量级任务,核心线程数应相对较小,避免线程过多导致资源竞争。
- 最大线程数(maximumPoolSize): 考虑系统的资源限制(如内存、CPU等)。最大线程数不宜设置过大,否则可能导致系统资源耗尽。对于高并发场景,结合任务的执行时间和资源消耗情况,一般可以将最大线程数设置为核心线程数的2 - 3倍,但需要根据实际压测进行调整。
- 队列容量(workQueue):
如果任务执行时间较短且并发量较大,可以选择无界队列(如
LinkedBlockingQueue
),但要注意可能会导致内存溢出问题。对于执行时间较长或资源消耗较大的任务,建议使用有界队列(如ArrayBlockingQueue
),以避免队列无限增长消耗过多内存。队列容量需要根据系统的处理能力和任务的预估数量来设置。 - 线程存活时间(keepAliveTime): 对于长时间运行的任务,线程存活时间可以设置得较短,例如1 - 2分钟,以避免空闲线程占用资源。对于短任务且并发量波动较大的场景,可以适当延长线程存活时间,如5 - 10分钟,减少线程创建和销毁的开销。
代码示例说明任务分类调度的核心逻辑
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class TaskSchedulerExample {
// 创建两个ScheduledThreadPoolExecutor,分别用于不同类型任务
private static ScheduledExecutorService shortTaskExecutor = Executors.newScheduledThreadPool(10);
private static ScheduledExecutorService longTaskExecutor = Executors.newScheduledThreadPool(5);
public static void main(String[] args) {
// 模拟短任务
Runnable shortTask = () -> {
System.out.println("Short task is running.");
// 短任务具体逻辑
};
ScheduledFuture<?> shortTaskFuture = shortTaskExecutor.scheduleAtFixedRate(shortTask, 0, 1, TimeUnit.SECONDS);
// 模拟长任务
Runnable longTask = () -> {
System.out.println("Long task is running.");
// 长任务具体逻辑,可能消耗较多资源
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
ScheduledFuture<?> longTaskFuture = longTaskExecutor.scheduleAtFixedRate(longTask, 0, 5, TimeUnit.SECONDS);
// 可以根据实际需求添加更多类型的任务和对应的线程池
}
}
在上述代码中,创建了两个ScheduledThreadPoolExecutor
,一个用于执行短任务,另一个用于执行长任务。通过不同的线程池对不同类型的任务进行分类调度,避免了长任务阻塞短任务的执行,提高了系统的整体性能和稳定性。同时,可以根据任务的资源消耗情况进一步优化线程池的参数配置。