Java並行プログラミング:並行コンテナCopyOnWriteArrayListの実装原理
COWと呼ばれるCopy-On-Writeは、プログラミングで使用される最適化戦略です。基本的な考え方は、全員が最初から同じコンテンツを共有しており、誰かがコンテンツを変更したい場合は、そのコンテンツをコピーして新しいコンテンツを作成し、それを変更するという一種の遅延戦略です。 JDK1.5 以降、Java 同時実行パッケージは、CopyOnWrite メカニズムを使用して実装された 2 つの同時コンテナ (CopyOnWriteArrayList と CopyOnWriteArraySet) を提供します。 CopyOnWrite コンテナは非常に便利で、多くの同時シナリオで使用できます。
CopyOnWriteコンテナとは
CopyOnWriteコンテナとは、書き込み時にコピーされるコンテナです。一般に理解されているのは、要素をコンテナに追加するとき、要素を現在のコンテナに直接追加するのではなく、まず現在のコンテナをコピーして新しいコンテナを作成し、要素を追加した後、その新しいコンテナに要素を追加するということです。次に、元のコンテナの参照が新しいコンテナを指すようにします。この利点は、現在のコンテナーは要素を追加しないため、ロックせずに CopyOnWrite コンテナーで同時読み取りを実行できることです。したがって、CopyOnWriteコンテナも読み書き分離の考え方であり、読み書きは別のコンテナです。
CopyOnWriteArrayListの実装原理
CopyOnWriteArrayListを使用する前に、ソースコードを読んでどのように実装されているかを理解しましょう。次のコードは、CopyOnWriteArrayList の add メソッドの実装 (CopyOnWriteArrayList に要素を追加する) です。追加するときにロックする必要があることがわかります。そうしないと、複数のスレッドで書き込むときに N 個のコピーがコピーされます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
読み取り時に複数のスレッドが CopyOnWriteArrayList にデータを追加している場合、書き込み時に古い CopyOnWriteArrayList がロックされないため、読み取りでは引き続き古いデータが読み取られます。
1 2 3 |
|
CopyOnWriteMap は JDK では提供されていません。CopyOnWriteArrayList を参照して実装できます。基本的なコードは次のとおりです。
13 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
CopyOnWrite メカニズムを理解していれば、実装は非常に簡単です。さまざまな CopyOnWrite コンテナを実装して、さまざまなアプリケーション シナリオで使用できます。 CopyOnWriteのアプリケーションシナリオCopyOnWrite同時コンテナは、読み取りが多く書き込みが少ない同時シナリオで使用されます。たとえば、ホワイトリスト、ブラックリスト、製品カテゴリへのアクセスと更新のシナリオでは、ユーザーはこの Web サイトの検索ボックスにキーワードを入力してコンテンツを検索しますが、一部のキーワードは検索できません。検索できないキーワードはブラックリストに登録され、毎晩更新されます。ユーザーが検索を行うと、現在のキーワードがブラックリストに含まれているかどうかがチェックされ、含まれている場合は検索を実行できないというメッセージが表示されます。実装コードは次のとおりです:
コードは非常にシンプルですが、CopyOnWriteMapを使用する際に注意する必要があることが2つあります: 1. 展開のオーバーヘッドを削減します。実際のニーズに応じて CopyOnWriteMap のサイズを初期化し、書き込み中の CopyOnWriteMap 拡張のオーバーヘッドを回避します。 2. 一括追加を使用します。追加するたびにコンテナがコピーされるため、追加の数を減らすことでコンテナのコピー回数を減らすことができます。たとえば、上記のコードでは addBlackList メソッドを使用します。 CopyOnWriteのデメリットCopyOnWriteコンテナには多くの利点がありますが、メモリ使用量とデータの一貫性という2つの問題もあります。そのため、開発時には注意が必要です。 メモリ使用量の問題。 CopyOnWrite のコピーオンライト メカニズムにより、書き込み操作が実行されると、古いオブジェクトと新しく書き込まれたオブジェクトという 2 つのオブジェクトが同時にメモリ内に常駐します (注: コピー中は、メモリ内の参照のみが保持されます)。コンテナは書き込み時にのみコピーされ、新しいオブジェクトが作成されて新しいコンテナに追加されますが、古いコンテナ内のオブジェクトはまだ使用されているため、オブジェクト メモリのコピーが 2 つ存在します。これらのオブジェクトが約 200M などの比較的大量のメモリを占有している場合、さらに 100M のデータを書き込むと 300M のメモリが占有されるため、Yong GC と Full GC が頻繁に発生する可能性があります。以前は、CopyOnWrite メカニズムを使用して大きなオブジェクトを毎晩更新するサービスをシステムで使用していました。その結果、毎晩 15 秒のフル GC が発生し、アプリケーションの応答時間も長くなりました。 メモリ使用量の問題に対処するには、コンテナ内の要素を圧縮することで、大きなオブジェクトのメモリ消費を減らすことができます。たとえば、要素がすべて 10 進数の場合、36 桁または 64 桁に圧縮することを検討できます。数字。または、CopyOnWrite コンテナを使用せず、ConcurrentHashMap などの他の同時コンテナを使用します。 データの整合性の問題。 CopyOnWrite コンテナはデータの最終的な整合性のみを保証できますが、データのリアルタイムの整合性は保証できません。したがって、書き込まれたデータをすぐに読み出したい場合は、CopyOnWrite コンテナを使用しないでください。 関連記事: Java 同時プログラミング: CountDownLatch、CyclicBarrier、およびセマフォ [JAVA 同時プログラミングの実践] ロックシーケンシャルデッドロック 関連ビデオ: |
以上がJava並行プログラミング:並行コンテナCopyOnWriteArrayListの実装原理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック

C++ での関数例外処理は、マルチスレッド環境でスレッドの安全性とデータの整合性を確保するために特に重要です。 try-catch ステートメントを使用すると、特定の種類の例外が発生したときにそれをキャッチして処理し、プログラムのクラッシュやデータの破損を防ぐことができます。

同時実行性とコルーチンは、GoAPI 設計で次の目的で使用されます。 高パフォーマンス処理: 複数のリクエストを同時に処理してパフォーマンスを向上させます。非同期処理: コルーチンを使用してタスク (電子メールの送信など) を非同期に処理し、メインスレッドを解放します。ストリーム処理: コルーチンを使用して、データ ストリーム (データベース読み取りなど) を効率的に処理します。

PHP マルチスレッドとは、1 つのプロセスで複数のタスクを同時に実行することを指します。これは、独立して実行されるスレッドを作成することによって実現されます。 PHP の Pthreads 拡張機能を使用して、マルチスレッド動作をシミュレートできます。インストール後、Thread クラスを使用してスレッドを作成および開始できます。たとえば、大量のデータを処理する場合、データを複数のブロックに分割し、対応する数のスレッドを作成して同時処理することで効率を向上させることができます。

ミューテックスは C++ でマルチスレッド共有リソースを処理するために使用されます。std::mutex を通じてミューテックスを作成します。 mtx.lock() を使用してミューテックスを取得し、共有リソースへの排他的アクセスを提供します。ミューテックスを解放するには mtx.unlock() を使用します。

マルチスレッド環境では、C++ メモリ管理はデータ競合、デッドロック、メモリ リークなどの課題に直面します。対策には次のものが含まれます: 1. ミューテックスやアトミック変数などの同期メカニズムの使用、 2. ロックフリーのデータ構造の使用、 4. (オプション) ガベージ コレクションの実装。

マルチスレッド プログラムのテストは、非再現性、同時実行エラー、デッドロック、可視性の欠如などの課題に直面しています。戦略には以下が含まれます。 単体テスト: 各スレッドの単体テストを作成して、スレッドの動作を検証します。マルチスレッド シミュレーション: シミュレーション フレームワークを使用して、スレッド スケジューリングを制御しながらプログラムをテストします。データ競合の検出: valgrind などのツールを使用して、潜在的なデータ競合を見つけます。デバッグ: デバッガー (gdb など) を使用して、ランタイム プログラムのステータスを調べ、データ競合の原因を見つけます。

並行関数の単体テストは、同時環境での正しい動作を確認するのに役立つため、非常に重要です。同時実行機能をテストするときは、相互排他、同期、分離などの基本原則を考慮する必要があります。並行機能は、シミュレーション、競合状態のテスト、および結果の検証によって単体テストできます。

マルチスレッド C++ では、例外処理は適時性、スレッドの安全性、明確性という原則に従います。実際には、ミューテックスまたはアトミック変数を使用することで、例外処理コードのスレッド セーフを確保できます。さらに、例外処理コードの再入性、パフォーマンス、テストを考慮して、コードがマルチスレッド環境で安全かつ効率的に実行されることを確認してください。
