2

私の小さなアプリケーションには、基本的にライターとリーダーの2つのクラスのスレッドがあります。1つのライターに複数のリーダーを割り当てることができます。ライターは、変数に書き込むことでリーダーと対話しchunkBufferます。

さて、ここでスレッドセーフの問題に頭を悩ませることはできませんchunkBuffer。静的ThreadLocal変数にを格納しないと、すべてのリーダーが単一のchunkBufferを共有することになります。これは悪いことです。しかし、chunkBufferを静的に格納するThreadLocalと、ライターは別のスレッドであり、chunkBufferの独自のコピーを取得して書き込みを続けますが、書き込むデータはリーダーに到達しません。ここで何が問題なのか説明してもらえますか?どうもありがとうございます。

編集言い換えると、スレッドサブクラス(ThreadLocalなど)のすべてのインスタンスに対して一意であるが、オンデマンドで他のスレッドからアクセスできるフィールドを作成する方法はありますか?

4

2 に答える 2

2

いいえ。

ThreadLocalは、スレッドプライベートデータ用です。あなたの場合、通信するオブジェクトが必要なので、他のタイプのオブジェクトが必要です。

使用するのに最適な構造は、同期されたキューだと思いますjava.util.concurrent.LinkedBlockingQueue<E>

キューを使用すると、プロデューサーはデータを挿入し、コンシューマーは消費することができます。同期している場合は、構造を壊すことなく、さまざまなスレッドから同期できます。

関連するライター/リーダー間でキューを共有できます。

Writer 1 -> queue 1 -> [readers A/B/C]

Writer 2 -> queue 2 -> [readers D/E/F]

各ライターとリーダーにはそれぞれのスレッドがあります。アイテムがない場合、各リーダーはキューブロッキングから1つのアイテムを取得しようとします。読者をより賢く管理する必要がある場合は、より洗練されたアプローチを試すことができますが、それは良い出発点だと思います。

于 2011-04-27T10:49:30.367 に答える
0

ThreadLocal変数を使用したくないと思います。本当に通知メカニズムが必要です。

Writerは次のことを行います。

  1. 読者に手紙を書くchunkBuffer
  2. 新しいデータをリーダーに通知します。

Javaの同時実行性でこれを行う方法はたくさんありますが、通常最も簡単で安全なのは、を使用することArrayBlockingQueueです。あなたのユースケースでは、各リーダーが独自のものを持っているように聞こえArrayBlockingQueue、それは単にキューから読み取る必要があります。

もちろん、それはあなたのユースケースに依存します。常に最新のデータで作業する必要がありますか、それとも各書き込みで作業する必要がありますchunkBufferか?これらの種類の質問は、必要なメカニズムを理解するために必要です。

注:同期キューについて言及するための@heliosへの小道具、うまくいけば私の答えは価値を追加します。

于 2011-04-27T11:03:30.087 に答える