Java 任务队列:ExecutorService 和 ThreadPoolExecutor

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java 任务队列:ExecutorService 和 ThreadPoolExecutor



在 Java 多线程应用程序中,任务及其执行的管理是关键任务之一。与其为每个任务创建新线程(这既昂贵又低效),开发者使用任务队列(Task Queues)结合线程池。这可以控制同时运行的线程数量、重用线程,并平稳处理峰值负载。



Java 中处理任务队列的基础是 java.util.concurrent 框架,该框架在 Java 5 中引入。主要组件包括:ExecutorService、ThreadPoolExecutor 以及各种 BlockingQueue 实现。



1. ExecutorService — 高级接口



ExecutorService 是一个接口,提供异步执行任务的方法。它隐藏了线程管理的细节。获取其实例的最流行方式是使用 Executors 类的工厂方法:



ExecutorService executor = Executors.newFixedThreadPool(4); // 4 个线程的线程池executor.submit(() -> {    System.out.println("任务在线程中执行:" + Thread.currentThread().getName());});executor.shutdown(); // 在所有任务完成后关闭


然而,工厂方法的配置能力有限。为了进行精细调整,可以直接使用 ThreadPoolExecutor。



2. ThreadPoolExecutor — 可配置的线程池



ThreadPoolExecutor 是该框架的核心。它接受任务队列、饱和策略、线程存活时间等参数。完整构造函数如下:



public ThreadPoolExecutor(    int corePoolSize,      // 最小线程数    int maximumPoolSize,   // 最大线程数    long keepAliveTime,    // 线程空闲后存活时间    TimeUnit unit,         // 时间单位    BlockingQueue<Runnable> workQueue, // 任务队列    RejectedExecutionHandler handler   // 溢出时的策略);


使用自定义队列创建线程池的示例:



BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);ThreadPoolExecutor executor = new ThreadPoolExecutor(    2, 4,    30, TimeUnit.SECONDS,    queue,    new ThreadPoolExecutor.AbortPolicy() // 默认策略 — 抛出异常);executor.execute(() -> {    // 繁重任务});executor.shutdown();


3. BlockingQueue — 任务队列的基础



队列类型决定了任务如何存储并传递给线程。最流行的实现包括:

  • LinkedBlockingQueue — 基于链表的无界队列。如果不设置容量,可能导致内存溢出。
  • ArrayBlockingQueue — 基于数组的有界队列。允许控制等待任务的数量。
  • SynchronousQueue — 零容量队列。每个任务直接传递给线程,无队列等待。
  • PriorityBlockingQueue — 优先级队列。任务按优先级排序(实现 Comparable)。


使用有界队列和拒绝策略的示例:



BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);ThreadPoolExecutor executor = new ThreadPoolExecutor(    2, 5,    10, TimeUnit.SECONDS,    queue,    new ThreadPoolExecutor.CallerRunsPolicy() // 任务在调用线程中执行);for (int i = 0; i < 20; i++) {    executor.submit(() -> {        Thread.sleep(100);        return Math.random();    });}executor.shutdown();


4. 饱和策略(RejectedExecutionHandler)



当队列溢出时

推荐