java併發程式設計工具類JUC第五篇:PriorityBlockingQueue優先順序佇列

語言: CN / TW / HK

在之前的文章中已經為大家介紹了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](http://my.oschina.net/u/1162528)
    public int compareTo(Employee emp) {
        return this.getId().compareTo(emp.getId());  //根據id排序
    }
 
    [@Override](http://my.oschina.net/u/1162528)
    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]

.

歡迎關注我的部落格,裡面有很多精品合集

本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格 - zimug.com

覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。