Java PriorityBlocking Que類を紹介します。

3080 ワード

Java PriorityBlocking Que類を紹介します。
この文章はPriorityBlockingQue類に焦点を合わせて、実例を通して勉強します。Queをすでに知っていると仮定して、まずPriorityBlockingQueクラスの元素が優先順位によって並べられていることを実証し、続いてこのタイプの列がスレッドをブロックするのに使えることを実証し、最後に2つの特性を組み合わせてマルチスレッド環境でデータを処理します。
元素の優先度
標準キューと違って、任意の要素を追加できません。要素は二つの条件を満たす必要があります。
  • Comprableインターフェース要素
  • を実現する。
  • は、Comprableインターフェース要素を実装しないで、Compratorコンパレータを提供します。
  • CompratorやComprableの要素を実現しました。PriorityBlockingQueの中の元素は順番に並べられています。コンパレータを実行する目的は、最優先の要素を第一位にすることであるので、キューから要素を削除すると、常に最優先の要素を削除することである。
    理解を容易にするために、まずシングルスレッドで使用します。複数のスレッドを使用しないと、要素が並べられていることを容易に証明できます。
    PriorityBlockingQueue queue = new PriorityBlockingQueue<>();
    ArrayList polledElements = new ArrayList<>();
      
    queue.add(1);
    queue.add(5);
    queue.add(2);
    queue.add(3);
    queue.add(4);
     
    queue.drainTo(polledElements);
     
    assertThat(polledElements).containsExactly(1, 2, 3, 4, 5);
    
    元素はランダムに添加されていますが、元素は順番に出ることを見ました。このときIntegerがComprableインターフェースを実現していますので、元素が昇順にキューから取り出されることを確認します。
    注意すべきことは、2つの要素の比較結果が同じである場合、両者の順序は保証されないことである。
    優先列ブロック機能
    標準キューを扱う場合は、poll法を使用して要素を取得しますが、キューが空であれば、poll法はnullに戻ります。PriorityBlockingQueはBlockingQueインターフェースを実現し、空き列から要素を削除する際にブロッキングが発生する追加の方法を追加しました。私たちは例を通してtake方法を実証した。
    PriorityBlockingQueue queue = new PriorityBlockingQueue<>();
     
    new Thread(() -> {
      System.out.println("Polling...");
     
      try {
          Integer poll = queue.take();
          System.out.println("Polled: " + poll);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
    }).start();
     
    Thread.sleep(TimeUnit.SECONDS.toMillis(5));
    System.out.println("Adding to queue");
    queue.add(1);
    
    簡単にsleep法を用いて実証したが、出力結果は以下の通りであった。
    Polling...
    Adding to queue
    Polled: 1
    
    take方法が新たな要素が加わるまでブロックされることを証明した:
  • スレッド印刷「Polling」証明スレッド起動
  • その後、テストプログラムは約5秒停止され、take方法及び
  • が実行されたことを証明します。
  • キューに要素を追加し、ほぼすぐに「Polled:1」を見て、takeメソッドが要素
  • に戻ることを証明します。
    BlockingQueインターフェースは、列がいっぱいになる時の渋滞方法を提供しています。しかし、PriorityBlockingQueの列は、いつまでもいっぱいにならないという意味で、常に新しい要素が追加される可能性があります。
    ブロックと優先度の両方の特性を同時に使用するデモ
    PriorityBlockingQueキューの2つの概念を説明します。例を挙げて両方を使って説明します。前の例を簡単に変更して、キューに追加します。
    Thread thread = new Thread(() -> {
        System.out.println("Polling...");
        while (true) {
            try {
                Integer poll = queue.take();
                System.out.println("Polled: " + poll);
            } 
            catch (InterruptedException e) { 
                e.printStackTrace();
            }
        }
    });
     
    thread.start();
     
    Thread.sleep(TimeUnit.SECONDS.toMillis(5));
    System.out.println("Adding to queue");
     
    queue.addAll(newArrayList(1, 5, 6, 1, 2, 6, 7));
    Thread.sleep(TimeUnit.SECONDS.toMillis(1));
    
    まずキュースレッドがブロックされてキューに要素が入るのを待ちます。次に、キューに要素を追加し、最後に優先順位で要素を処理するキューを表示します。出力結果は以下の通りです。
    Polling...
    Adding to queue
    Polled: 1
    Polled: 1
    Polled: 2
    Polled: 5
    Polled: 6
    Polled: 6
    Polled: 7
    
    締め括りをつける
    本論文ではPriorityBlockingQueキューの二つの特性を実証した。優先順位に従って処理し、空き列の状況に対して、取得方法はスレッドをブロックする。