zoukankan      html  css  js  c++  java
  • java并发编程工具类JUC第五篇:PriorityBlockingQueue优先级队列

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue,本文为系列文章第五篇。

    Java PriorityBlockingQueue队列是BlockingQueue接口的实现类,它根据priority优先级确定队列内元素对象的处理顺序,也就是说在一个PriorityBlockingQueue队列中,被添加到队列中的元素,根据priority进行排序。PriorityBlockingQueue具有BlockingQueue阻塞队列的一些特性,如果您不熟悉BlockingQueue可以参看我之前的文章。

    1. PriorityBlockingQueue 特性

    • PriorityBlockingQueue 是一个无界队列(队列内元素个数没有上限),队列容量可以自动增长。其初始化队列容量为11,也可以通过构造函数参数initialCapacity指定其初始化容量。
    • 不接受 NULL对象插入到PriorityBlockingQueue
    • 添加到PriorityBlockingQueue队列中的元素对应的Java类,通常需要实现Comparable接口或者是可以默认排序的对象(如数字、字符串),否则会抛出ClassCastException
    • 可以使用java8 的Comparator提供自定义队列内元素的排序规则,后文会举例说明。
    • 如果存在多个对象拥有相等的优先级,从队列中poll获取元素的时候可能获取到其中任何一个元素。
    • PriorityBlockingQueue 是线程安全的

    2. PriorityBlockingQueue 应用实例

    我们写一个类Employee,该类实现了Comparable接口,所以其实例对象可以根据compareTo()函数定义的规则进行排序。

    public class Employee implements Comparable<Employee> {
    
        private Long id;
        private String name;
        private LocalDate dob;
        //Getters and setters
    
        public Employee(Long id, String name, LocalDate dob) {
            super();
            this.id = id;
            this.name = name;
            this.dob = dob;
        }
         
        @Override
        public int compareTo(Employee emp) {
            return this.getId().compareTo(emp.getId());  //根据id排序
        }
     
        @Override
        public String toString() {
            return "Employee [id=" + id + ", name=" + name + ", dob=" + dob + "]";
        }
    }
    

    构造一个PriorityBlockingQueue对象,并向其内部加入若干Employee对象,并使用poll方法从队列内取出元素。

    PriorityBlockingQueue<Employee> priorityBlockingQueue = new PriorityBlockingQueue<>();
    
    priorityBlockingQueue.add(new Employee(1l, "AAA", LocalDate.now()));
    priorityBlockingQueue.add(new Employee(4l, "CCC", LocalDate.now()));
    priorityBlockingQueue.add(new Employee(5l, "BBB", LocalDate.now()));
    priorityBlockingQueue.add(new Employee(2l, "FFF", LocalDate.now()));
    priorityBlockingQueue.add(new Employee(3l, "DDD", LocalDate.now()));
    priorityBlockingQueue.add(new Employee(6l, "EEE", LocalDate.now()));
    
    while(true) {
      Employee e = priorityBlockingQueue.poll();
      System.out.println(e);
    
      if(e == null) break;
    }
    

    根据上文中compareTo()方法定义的排序规则,按照id为优先级,所以从队列中拿出对象并打印的顺序如下:

    Employee [id=1, name=AAA, dob=2021-03-25]
    Employee [id=2, name=FFF, dob=2021-03-25]
    Employee [id=3, name=DDD, dob=2021-03-25]
    Employee [id=4, name=CCC, dob=2021-03-25]
    Employee [id=5, name=BBB, dob=2021-03-25]
    Employee [id=6, name=EEE, dob=2021-03-25]
    

    3. 使用 Java8 Comparator 做优先级排序的实例

    我们可以使用java 8 Comparator排序器,来定义优先级排序规则。使用构造方法PriorityBlockingQueue(int initialCapacity, Comparator comparator) 构造PriorityBlockingQueue队列。

    //以员工名称的字符串自然正序进行排序
    Comparator<Employee> nameSorter = Comparator.comparing(Employee::getName);
     
    PriorityBlockingQueue<Employee> priorityBlockingQueue = new PriorityBlockingQueue<>( 11, nameSorter );
    
    //此处省略向队列中添加对象,及循环取出对象打印的代码,参考上文
    

    按照员工姓名进行优先级排序,所以打印顺序AAA、BBB、CCC、DDD、EEE、FFF

    Employee [id=1, name=AAA, dob=2021-03-25]
    Employee [id=5, name=BBB, dob=2021-03-25]
    Employee [id=4, name=CCC, dob=2021-03-25]
    Employee [id=3, name=DDD, dob=2021-03-25]
    Employee [id=6, name=EEE, dob=2021-03-25]
    Employee [id=2, name=FFF, dob=2021-03-25]
    

    .

  • 相关阅读:
    使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
    便携版WinSCP在命令行下同步文件夹
    ffmpeg (ffprobe)分析文件关键帧时间点
    sqlite删除数据或者表后,回收数据库文件大小
    ubuntu 20.04下 freeswitch 配合 fail2ban 防恶意访问
    ffmpeg使用nvenc编码的结论记录
    PC版跑跑卡丁车 故事模式 亚瑟传说章节 卡美洛庆典 2阶段 心灵之眼 攻略
    There was an error loading or playing the video
    Nvidia RTX Voice 启动报错修复方法
    火狐浏览器 关闭跨域限制
  • 原文地址:https://www.cnblogs.com/zimug/p/14848507.html
Copyright © 2011-2022 走看看