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]
    

    .

  • 相关阅读:
    原生JS实现日历
    重复的事情让机器来做,简化的思想
    Ext3.1的一些使用讨论
    JS使用Crypto实现AES/ECS/zero-padding加密
    一些提升效率的小知识
    一些很有意思的JS现象
    Tiny Linux -- tce-load
    python sqlalchemy mysql 自动映射
    python 反射
    python 动态导包
  • 原文地址:https://www.cnblogs.com/zimug/p/14848507.html
Copyright © 2011-2022 走看看