データを転送するには、すべてのスレッドが利用できるフィールドが必要です。あなたの場合、複数のエントリを処理するには、ある種のコレクションである必要があります。final
たとえばConcurrentLinkedQueue を参照して field を作成した場合は、ほぼ完了です。フィールドを公開して誰もが見ることができるようにするか、getter で使用できるようにすることができます。
非同期キューを使用する場合は、そのキューへのすべてのアクセスを手動で同期する必要があるため、やるべきことが増えます。つまり、すべての使用状況を追跡する必要があります。ゲッターメソッドがあると簡単ではありません。同時アクセスからキューを保護する必要があるだけでなく、相互に依存する呼び出しが同じ同期ブロックで終了することを確認する必要があります。例えば:
if (!queue.isEmpty()) obj = queue.remove();
全体が同期さqueue
れていない場合は、空ではないことを完全に伝えることができ、次の要素を取得しようとすると NoSuchElementException がスローされます。(ConcurrentLinkedQueue のインターフェイスは、1 回のメソッド呼び出しでこのような操作を実行できるように特別に設計されています。使用したくない場合でも、よく見てください。)
簡単な解決策は、メソッドが慎重に選択され、すべてが同期されている別のオブジェクトでキューをラップすることです。ラップされたクラスは、それが LinkedList または ArrayList であっても、CLQ のように動作し (正しく実行すれば)、プログラムの残りの部分に自由に解放できます。
そのfinal
ため、(たとえば) LinkedList を含み、LinkedList を使用してデータを格納およびアクセスする同期メソッドを持つラッパー クラスへの不変 ( ) 参照を持つ、実際にはグローバル フィールドとなるものがあります。CLQ のようなラッパー クラスは、スレッド セーフになります。
これに関するいくつかの変形が望ましいかもしれません。ラッパーをプログラム内の他の高レベル クラスと組み合わせることが理にかなっている場合があります。ネストされたクラスのインスタンスを作成して使用可能にすることも理にかなっています。おそらく、キューに追加するだけのものとキューから削除するだけのものです。(CLQ ではこれを行うことができませんでした。)
最後の注意: すべてを同期したら、次のステップは、スレッドの安全性を損なうことなく (スレッドが過度に待機しないようにするために) 同期を解除する方法を理解することです。これに一生懸命取り組むと、ConcurrentLinkedQueue を書き直すことになります。