当前位置: 首页 > article >正文

如何设计一个能根据任务优先级来执行的线程池

  • 不同的线程池会选用不同的阻塞队列作为任务队列,比如FixedThreadPool 使用的是LinkedBlockingQueue(有界队列),默认构造器初始的队列长度为 Integer.MAX_VALUE ,由于队列永远不会被放满,因此FixedThreadPool最多只能创建核心线程数的线程。
  • 假如需要实现一个优先级任务线程池的话,那可以考虑使用 PriorityBlockingQueue (优先级阻塞队列)作为任务队列(ThreadPoolExecutor 的构造函数有一个 workQueue 参数可以传入任务队列)。

要想让 PriorityBlockingQueue 实现对任务的排序,传入其中的任务必须是具备排序能力的,方式有两种:

实现 Comparable 接口

提交到线程池的任务实现 Comparable 接口,并重写 compareTo 方法来指定任务之间的优先级比较规则。
缺点:1.任务类必须实现 Comparable 接口,硬编码不够灵活。2.如果需要多种优先级规则,任务类代码会变得复杂。

import java.util.concurrent.*;

public class PriorityTask implements Runnable, Comparable<PriorityTask> {
    private final int priority;
    private final String name;

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

    @Override
    public void run() {
        System.out.println("Executing task: " + name + " with priority: " + priority);
    }

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

public class PriorityThreadPoolExecutor extends ThreadPoolExecutor {
    public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, new PriorityBlockingQueue<Runnable>());
    }
}


//使用示例
public class Main {
    public static void main(String[] args) {
        PriorityThreadPoolExecutor executor = new PriorityThreadPoolExecutor(2, 4, 1, TimeUnit.MINUTES);
        executor.execute(new PriorityTask(10, "Low priority task"));
        executor.execute(new PriorityTask(1, "High priority task"));
        executor.execute(new PriorityTask(5, "Medium priority task"));
        executor.shutdown();
    }
}

Comparator

创建 PriorityBlockingQueue 时传入一个 Comparator 对象来指定任务之间的排序规则(推荐)。

import java.util.concurrent.*;

public class Task implements Runnable {
    private final int priority;
    private final String name;

    public Task(int priority, String name) {
        this.priority = priority;
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("Executing task: " + name + " with priority: " + priority);
    }

    public int getPriority() {
        return priority;
    }
}

public class PriorityThreadPoolExecutor extends ThreadPoolExecutor {
    public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
              new PriorityBlockingQueue<>(11, Comparator.comparingInt(Task::getPriority)));
    }
}


//使用示例
public class Main {
    public static void main(String[] args) {
        PriorityThreadPoolExecutor executor = new PriorityThreadPoolExecutor(2, 4, 1, TimeUnit.MINUTES);
        executor.execute(new Task(10, "Low priority task"));
        executor.execute(new Task(1, "High priority task"));
        executor.execute(new Task(5, "Medium priority task"));
        executor.shutdown();
    }
}


http://www.kler.cn/a/472540.html

相关文章:

  • Mac-docker配置
  • Spring项目创建流程及配置文件bean标签参数简介
  • 【Logstash03】企业级日志分析系统ELK之Logstash 过滤 Filter 插件
  • 如何让用户在网页中填写PDF表格?
  • Chrome访问https页面显示ERR_CERT_INVALID,且无法跳过继续访问
  • 从Linux本地软件存储库安装MySQL
  • 计算机的错误计算(二百零五)
  • RPM包的制作
  • HTML5实现好看的中秋节网页源码
  • 《浮岛风云》V1.0中文学习版
  • 接口项目uuid算法开发及验证-thinkphp6-rabbitmq
  • 大模型(LLM)面试全解:主流架构、训练目标、涌现能力全面解析
  • 20250108-实验+神经网络
  • 2025年01月08日Github流行趋势
  • 你好,2025!JumpServer开启新十年
  • 解决 uniapp 开发中的相机相册权限申请同步告知目的问题(兼容 Android 13)| 华为应用商店上架解决方案
  • 【C语言】_冒泡排序及其优化思路
  • 用Python实现货运分析地图应用
  • 经典多模态模型CLIP - 直观且详尽的解释
  • onLoad 生命周期函数是否执行取决于跳转的方式和小程序的页面栈管理机制
  • 移动支付安全:五大威胁及防护策略
  • spark functions函数合集(无示例)
  • dockerfile 中 #(nop)
  • 物联网协议:比较MQTT、CoAP和HTTP以实现高效设备通信
  • 【Leetcode 热题 100】33. 搜索旋转排序数组
  • vulnhub靶场-Deathnote(至获取shell)