ホームページ Java &#&はじめる Javaキューとは何ですか

Javaキューとは何ですか

Nov 14, 2019 am 10:56 AM
java

Javaキューとは何ですか

キューは、「先入れ先出し」の原則に従う特別な線形テーブルです。私たちの日常的な使用では、データを同時に操作するためによく使用されます。並行プログラミングでは、スレッドセーフなキューの使用が必要になる場合があります。スレッドセーフ キューを実装する場合は、通常 2 つの方法があります。1 つはブロッキング キューを使用する方法、もう 1 つはスレッド同期ロックを使用する方法です。

ブロッキング キューとは何ですか?

パン屋があり、客がパンを食べ、シェフがパンを焼いているとします。かごの中のパンは2個までで、テストが終わったらシェフがパンをかごに入れ、ゲストがパンを食べるときはかごからパンを取り出します。ゲストがパンを食べるときにカゴの中にパンがあるか、シェフがパンを焼くときにカゴが溢れていないのか、このとき、ブロッキングキューの概念を導入する必要があります。これは、私たちがよく生産者-消費者モデルと呼ぶものです。

ブロッキング キューは、2 つの追加操作をサポートするキューです。これら 2 つの追加操作は、挿入および削除メソッドのブロックをサポートします。

(1) ブロッキング挿入メソッドのサポート: これは、キューがいっぱいになると、キューがいっぱいになるまで要素を挿入するスレッドをブロックすることを意味します。

(2) ブロッキング削除メソッドのサポート: これは、キューが空の場合、要素を取得するスレッドはキューが空でなくなるまで待機することを意味します。ブロッキング キューは、プロデューサーおよびコンシューマーのシナリオでよく使用されます。プロデューサーはキューに要素を追加するスレッドであり、コンシューマーはキューから要素を取得するスレッドです。ブロッキング キューは、プロデューサーが要素を保存するために使用し、コンシューマーが要素を取得するために使用するコンテナです。

システム内のノンブロッキング キュー: PriorityQueue と ConcurrentLinkedQueue

ノンブロッキング キュー間の関係を見てみましょう (PriorityQueue を例にします):

Javaキューとは何ですか

PriorityQueue クラスは AbstractQueue を継承し、Serializable インターフェイスを実装します。基本的に順序付きリストを維持する PriorityQueue は Java util パッケージにあります。名前の前半の Priority という単語は優先順位を意味します。実際、このキューには「優先順位」があります。キューに追加された要素は、自然な順序に従って (java.util.Comparable 実装を通じて)、またはコンストラクターに渡された java.util.Comparator 実装に従って配置されます。

ConcurrentLinkedQueue は、リンクされたノードに基づくスレッドセーフなキューです。同時アクセスには同期は必要ありません。 ConcurrentLinkedQueue はキューの末尾に要素を追加し、先頭から要素を削除するため、キューのサイズがわからなくても、共通コレクションへの ConcurrentLinkedQueue の共有アクセスは問題なく機能します。キュー サイズに関する情報の収集には時間がかかり、キューをトラバースする必要があります。ConcurrentLinkedQueue は、リンクされたノードに基づく無制限のスレッドセーフ キューです。先入れ先出しルールを使用してノードを並べ替えます。要素を追加すると、キューの最後尾に追加されます。要素を取得すると、キューの先頭の要素が返されます。

ブロッキング インターフェイスを実装するキュー:

BlockingQueue インターフェイスと 5 つのブロッキング キュー クラスが java.util.concurrent に追加されます。これは本質的には FIFO データ構造にひねりが加えられたものです。キューに要素をすぐに追加または削除するのではなく、スペースまたは要素が使用可能になるまで操作を実行するスレッドはブロックされます。

5 つのキューは、それぞれ異なるものを提供します。

·ArrayBlockingQueue: 配列によってサポートされる境界付きキュー。

·LinkedBlockingQueue: リンクされたノードによってバックアップされるオプションの制限付きキュー。

·PriorityBlockingQueue: 優先度ヒープを基盤とする無制限の優先度キュー。

·DelayQueue: 優先度ヒープに基づく時間ベースのスケジューリング キュー。

·SynchronousQueue: BlockingQueue インターフェイスを使用した単純なランデブー メカニズム。

ArrayBlockingQueue と LinkedBlockingQueue の間の継承関係を見てみましょう:

Javaキューとは何ですか

Javaキューとは何ですか

次の間の継承関係を見てみましょう。この 2 つのクラスは、AbstractQueue から継承し、Serializable インターフェイスも実装していることがわかりますが、違いは、BlockingQueue インターフェイスも実装していることです。

いくつかを簡単に紹介しましょう:

LinkedBlockingQueueLinkedBlockingQueue のデフォルト サイズは Integer.MAX_VALUE で、キャッシュされた境界付き待機キューとして理解できます。最大容量を指定することを選択できます。リンク リストに基づくキューです。このキューは、FIFO に従って要素を並べ替えます。 (先入先出)。プロデューサがデータをキューに入れると、そのデータはキュー内にキャッシュされます。キュー バッファが最大キャッシュ容量に達すると (LinkedBlockingQueue はコンストラクタを通じてこの値を指定できます)、コンシューマがデータを消費するまで、プロデューサ キューはブロックされます。データの一部がドロップされると、プロデューサ スレッドが起動され、コンシューマではその逆が行われます。

ArrayBlockingQueue は構築時に容量を指定する必要があり、公平性が必要かどうかを選択できます。公平性パラメータが true に設定されている場合、待ち時間が最も長いスレッドが最初に処理されます (実際には、ReentrantLock を に設定することで実現されます)。 true この種の公平性: つまり、待機時間が最も長いスレッドが最初に動作します)。一般に、公平性を高めるとパフォーマンスが低下するため、本当に必要な場合にのみ使用してください。これは、FIFO (先入れ先出し) 原則に従って要素を並べ替える、配列ベースのブロッキング循環キューです。

PriorityBlockingQueue は優先キューであり、先入れ先出しキューではありません。要素は優先度の順に削除され、キューには上限がありません (ソース コードを見ると、PriorityBlockingQueue はヒープ データ構造に基づいて PriorityQueue を再パッケージしたものであり、PriorityQueue には ArrayList と同様に容量制限がありません。ブロッキング キューに入れるときはブロックされません。このキューは論理的には制限されていませんが、リソースが使い果たされているため、追加操作を実行しようとすると OutOfMemoryError が発生する可能性があります)、ただし、キューが空の場合、要素の取得はブロックされるため、その取得操作のテイクはブロックされます。さらに、キューに入る要素には比較機能が必要です。

ConcurrentLinkedQueue と LinkedBlockingQueue について:

は、ブロッキング キューと非ブロッキング キューの違いとしても理解できます:

1.LinkedBlockingQueue は、ロック メカニズムでは、ConcurrentLinkedQueue は CAS アルゴリズムを使用しますが、LinkedBlockingQueue の基礎となるロックの取得にも CAS アルゴリズムが使用されます。

2. 要素の取得に関して、ConcurrentLinkedQueue は要素を取得するためのブロックをサポートしていませんが、LinkedBlockingQueue はブロックする take() メソッドをサポートしています。

3. 要素挿入のパフォーマンスについては、特にマルチ CPU サーバーで実際に使用すると、ロックとロックなしの差が反映され、ConcurrentLinkedQueue は LinkedBlockingQueue よりもはるかに高速になります。

プロデューサー - コンシューマー コード:

プロデューサー - コンシューマーの小さな例をインターネット上で見ましたが、これはブロッキング キューを理解するのに非常に役立ちます。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class BlockingQueueTest {
    public static class Basket {
        BlockingQueue<String> basket = new ArrayBlockingQueue<>(3);
 
        private void produce() throws InterruptedException {
            basket.put("苹果");
        }
 
        private void consume() throws InterruptedException {
            basket.take();
        }
 
        private int getAppleNumber() {
            return basket.size();
        }
    }
 
    private static void testBasket() {
        final Basket basket = new Basket();
        class Producer implements Runnable {
            public void run() {
                try {
                    while (true) {
                        System.out.println("生产者开始生产苹果###");
                        basket.produce();
                        System.out.println("生产者生产苹果完毕###");
                        System.out.println("篮子中的苹果数量:" + basket.getAppleNumber() + "个");
                        Thread.sleep(300);
                    }
                } catch (InterruptedException e) {}
            }
        }
 
        class Consumer implements Runnable {
            public void run() {
                try {
                    while (true) {
                        System.out.println("消费者开始消费苹果***");
                        basket.consume();
                        System.out.println("消费者消费苹果完毕***");
                        System.out.println("篮子中的苹果数量:" + basket.getAppleNumber() + "个");
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {}
            }
        }
        ExecutorService service = Executors.newCachedThreadPool();
        Producer producer = new Producer();
        Consumer consumer = new Consumer();
        service.submit(producer);
        service.submit(consumer);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {}
        service.shutdownNow();
    }
 
    public static void main(String[] args) {
        BlockingQueueTest.testBasket();
    }
}
ログイン後にコピー

多くの Java トレーニング ビデオ はすべて PHP 中国語 Web サイトにあります。オンラインで学習することを歓迎します。

以上がJavaキューとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

See all articles