MST

星途 面试题库

面试题:Java线程池搭配LinkedBlockingQueue时的饱和策略调整

在Java线程池中,若使用LinkedBlockingQueue作为任务队列,当队列已满且线程池达到最大线程数时,会触发饱和策略。请说明默认的饱和策略是什么,并详细阐述如何自定义饱和策略来满足特定业务需求,比如优先处理某些高优先级任务。
15.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 默认饱和策略
    • 在Java线程池中,当使用LinkedBlockingQueue作为任务队列,且队列已满且线程池达到最大线程数时,默认的饱和策略是AbortPolicyAbortPolicy会直接抛出RejectedExecutionException异常,阻止系统正常运行。例如:
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(1);
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 10, TimeUnit.SECONDS, queue);
    // 当提交任务超过队列容量和最大线程数时,会抛出RejectedExecutionException异常
    threadPoolExecutor.submit(() -> System.out.println("Task"));
    
  2. 自定义饱和策略以优先处理高优先级任务
    • 首先,定义一个实现RejectedExecutionHandler接口的类来实现自定义饱和策略。假设我们的任务有优先级,这里用一个简单的PriorityTask类表示任务,包含优先级字段。
    class PriorityTask implements Runnable {
        private int priority;
        @Override
        public void run() {
            System.out.println("Running task with priority " + priority);
        }
        public PriorityTask(int priority) {
            this.priority = priority;
        }
        public int getPriority() {
            return priority;
        }
    }
    class PriorityRejectedExecutionHandler implements RejectedExecutionHandler {
        private final BlockingQueue<Runnable> queue;
        public PriorityRejectedExecutionHandler(BlockingQueue<Runnable> queue) {
            this.queue = queue;
        }
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            if (!executor.isShutdown()) {
                try {
                    // 将任务按优先级插入队列
                    queue.put(new PrioritizedRunnable((PriorityTask) r));
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
    class PrioritizedRunnable implements Comparable<PrioritizedRunnable> {
        private PriorityTask task;
        public PrioritizedRunnable(PriorityTask task) {
            this.task = task;
        }
        @Override
        public void run() {
            task.run();
        }
        @Override
        public int compareTo(PrioritizedRunnable o) {
            return Integer.compare(task.getPriority(), o.task.getPriority());
        }
    }
    
    • 然后,在创建ThreadPoolExecutor时使用自定义的饱和策略。
    BlockingQueue<Runnable> priorityQueue = new PriorityBlockingQueue<>();
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
            1,
            2,
            10,
            TimeUnit.SECONDS,
            priorityQueue,
            new PriorityRejectedExecutionHandler(priorityQueue));
    executor.submit(new PriorityTask(2));
    executor.submit(new PriorityTask(1));
    executor.shutdown();
    
    在上述代码中,PriorityRejectedExecutionHandler类实现了RejectedExecutionHandler接口,当任务被拒绝时,它会将任务按照优先级插入到PriorityBlockingQueue中,使得高优先级任务能够优先被处理。PriorityTask类表示带有优先级的任务,PrioritizedRunnable类用于实现比较功能,以便在队列中按优先级排序。