导读:本期聚焦于小伙伴创作的《在Java中线程池队列有哪些类型,任务调度机制是怎样的》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《在Java中线程池队列有哪些类型,任务调度机制是怎样的》有用,将其分享出去将是对创作者最好的鼓励。

Java线程池队列类型介绍

Java线程池的核心实现类是ThreadPoolExecutor,其构造方法中的workQueue参数用于指定任务队列,所有队列都实现了BlockingQueue接口,常见的队列类型有以下几种:

在Java中线程池队列有哪些类型,任务调度机制是怎样的

1. ArrayBlockingQueue

基于数组实现的有界阻塞队列,创建时需要指定队列容量,队列满时再提交任务会根据线程池的拒绝策略处理。适合需要严格控制任务积压数量的场景,避免内存溢出。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ArrayBlockingQueueDemo {
    public static void main(String[] args) {
        // 创建核心线程数为2,最大线程数为4,队列容量为10的线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                4,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(10)
        );
        // 提交15个任务,当队列满后才会创建非核心线程
        for (int i = 0; i < 15; i++) {
            int taskId = i;
            executor.execute(() -> {
                System.out.println("执行任务:" + taskId + ",线程名:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.shutdown();
    }
}

2. LinkedBlockingQueue

基于链表实现的阻塞队列,默认是无界的(容量为Integer.MAX_VALUE),也可以指定容量创建有界队列。无界队列下线程池的最大线程数参数会失效,因为队列永远不会满,不会创建非核心线程,适合任务量波动大但不需要限制积压的场景。

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class LinkedBlockingQueueDemo {
    public static void main(String[] args) {
        // 使用无界LinkedBlockingQueue,最大线程数参数不生效
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                4,
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>()
        );
        // 提交大量任务,只会创建2个核心线程,任务全部进入队列
        for (int i = 0; i < 20; i++) {
            int taskId = i;
            executor.execute(() -> {
                System.out.println("执行任务:" + taskId + ",线程名:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.shutdown();
    }
}

3. SynchronousQueue

同步移交队列,本身不存储元素,每个插入操作必须等待另一个线程的移除操作,否则插入线程会阻塞。使用该队列时,提交的任务会直接交给线程执行,如果没有空闲线程则会创建新线程,直到达到最大线程数,适合要求高吞吐、任务处理快的场景。

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class SynchronousQueueDemo {
    public static void main(String[] args) {
        // 使用SynchronousQueue,提交任务直接尝试交给线程执行
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                4,
                60,
                TimeUnit.SECONDS,
                new SynchronousQueue<>()
        );
        // 提交5个任务,会创建2个核心线程+3个非核心线程执行
        for (int i = 0; i < 5; i++) {
            int taskId = i;
            executor.execute(() -> {
                System.out.println("执行任务:" + taskId + ",线程名:" + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.shutdown();
    }
}

4. PriorityBlockingQueue

支持优先级的无界阻塞队列,任务需要实现Comparable接口或者通过构造方法传入Comparator,队列会根据优先级排序,优先级高的任务会先被执行,适合需要按优先级处理任务的场景。

import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

// 实现Comparable接口的任务类
class PriorityTask implements Runnable, Comparable<PriorityTask> {
    private int priority;
    private int taskId;

    public PriorityTask(int priority, int taskId) {
        this.priority = priority;
        this.taskId = taskId;
    }

    @Override
    public void run() {
        System.out.println("执行任务ID:" + taskId + ",优先级:" + priority + ",线程名:" + Thread.currentThread().getName());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public int compareTo(PriorityTask o) {
        // 优先级数值越小,优先级越高
        return Integer.compare(this.priority, o.priority);
    }
}

public class PriorityBlockingQueueDemo {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                2,
                60,
                TimeUnit.SECONDS,
                new PriorityBlockingQueue<>()
        );
        // 提交不同优先级的任务
        executor.execute(new PriorityTask(3, 1));
        executor.execute(new PriorityTask(1, 2));
        executor.execute(new PriorityTask(2, 3));
        executor.execute(new PriorityTask(0, 4));
        executor.shutdown();
    }
}

5. DelayedWorkQueue

这是ScheduledThreadPoolExecutor默认使用的队列,用于支持定时任务和周期性任务,队列中的任务会按照延迟时间排序,只有延迟时间到达的任务才会被取出执行。

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class DelayedWorkQueueDemo {
    public static void main(String[] args) {
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
        // 提交一个延迟3秒执行的任务
        executor.schedule(() -> {
            System.out.println("延迟3秒执行的任务,线程名:" + Thread.currentThread().getName());
        }, 3, TimeUnit.SECONDS);
        // 提交一个初始延迟1秒,之后每隔2秒执行的周期性任务
        executor.scheduleAtFixedRate(() -> {
            System.out.println("周期性执行的任务,线程名:" + Thread.currentThread().getName());
        }, 1, 2, TimeUnit.SECONDS);
    }
}

Java线程池任务调度机制说明

线程池的任务调度流程遵循固定的规则,当调用execute()或者submit()方法提交任务时,会按以下步骤处理:

调度流程步骤

  • 第一步:如果当前运行的线程数小于核心线程数,直接创建新的核心线程执行提交的任务,不管是否有核心线程空闲。
  • 第二步:如果当前运行的线程数已经达到核心线程数,会将任务放入阻塞队列中等待。
  • 第三步:如果队列已满,且当前运行的线程数小于最大线程数,会创建非核心线程执行任务。
  • 第四步:如果当前运行的线程数已经达到最大线程数,且队列已满,会触发线程池的拒绝策略,处理无法执行的任务。

拒绝策略说明

当任务无法被线程池执行时,会触发以下四种内置拒绝策略:

拒绝策略类策略说明
AbortPolicy默认策略,直接抛出RejectedExecutionException异常,中断任务提交流程
CallerRunsPolicy用提交任务的线程来执行任务,会降低任务提交速度,给线程池缓冲时间
DiscardPolicy直接丢弃任务,不做任何处理也不抛出异常
DiscardOldestPolicy丢弃队列中最旧的未执行任务,然后尝试重新提交当前任务

调度机制注意事项

非核心线程在空闲时间超过keepAliveTime后会被回收,而核心线程默认不会回收,除非设置了allowCoreThreadTimeOuttrue。另外,使用无界队列时,因为队列永远不会满,所以永远不会触发非核心线程的创建,最大线程数参数会失效,实际运行线程数不会超过核心线程数。

在实际开发中,需要根据任务的类型选择合适的队列:CPU密集型任务适合使用较小的队列容量,避免任务积压导致响应变慢;IO密集型任务可以使用稍大的队列容量,充分利用线程资源。同时要避免使用无界队列处理不可控的任务量,防止内存溢出问题。

线程池BlockingQueue任务调度ThreadPoolExecutor修改时间:2026-07-06 11:21:16

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。