2017-12-07 53 views
0

私はマップを通してループしていますが、私はいくつかのスレッドを持っています。 マップのキューにはアクションが含まれています。私の目標は、すべてのスレッドに実行するアクションを与えることです.2つのスレッド(またはそれ以上)は1つのキューから2つのタスク(またはそれ以上)を実行できません。 すべてのスレッドがキューを検索し、キューにアクションがあるかどうかを確認します(はいの場合)。アクションを実行する別のキューを検索しない場合は、キューの1つを実行します。 注:キューの数は、別のスレッドが実行するアクションを探している場合はつもりであるということです私は「のMap.Entry」同期とセマフォ

 public void run() { 

      while (true) { 
       Action<?> act; 
       for (Map.Entry entry :ActionMap.entrySet()) { 
        Synchronized(entry) 
        { 
         act = ((Queue<Action>)entry.getValue()).poll(); 
         if (act == null) 
         break; 
        } 
       } 

      } 
      } 

問題で同期しようとした 電子 スレッドの数よりも大きくすることができます最初のスレッドがタスクを完了したり、待っているのを待っていて、それが私が望んでいないものであることを同期したLine And Waitに詰め込まれている。 私はいくつかのスレッドが別のスレッドがそれをスキップして

はので、私は周りに掘っ検索を続ける上で作業しているキューに到達した場合は、キューを検索するためのスレッドのすべてをしたいとセマフォたので、私はこの

Semaphore Gate = new Semaphore(1); 



     public void run() { 

      while (true) { 
       Action<?> act; 
       for (Map.Entry entry :ActionMap.entrySet()) { 
        if(Gate.tryAcquire()); 
        { 
         act = ((Queue<Action>)entry.getValue()).poll(); 
         if (act == null){ 
        Gate.Release(); 
        break; 

         } 
         else { 
         act.handle(); 
         Gate.Release(); 
        } 
        } 
       } 

      } 
      } 
に達しました

はGate.aquireは()すべてのエントリが それが2つのdiffirentエントリおよび2つの異なるスレッドが1つだけのスレッドがゲートにアクセスし、アクション

を実行できることを意味しますので、最終的にはいずれかの用量つもりロックしているであることをこれで問題を置きます私を助けることができるデザインパターン? ありがとうございました...

+0

[XY問題](https://meta.stackexchange.com/a/66378)のように聞こえます。マップをスキャンしてスレッドを[スレッドプール](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html)にサブミットするだけの場合はどうでしょうか? ? –

+0

私は説明の中で私は明確ではないと感じる私は2つの考えを与え、彼らは私が欲しいものを私に与えていないと言った...私は私の問題をクリアするためにした..私はどのように私のコードを変更する。あなたの解決策は、私はエントリを持っていない他のエントリは、各エントリは、このキュー内のキューを含んでいるスレッドの仕事は、エントリ(キュー)を見つけて、アクションを実行することです..それらについて知っているいくつかの制約と..上に読むことができます.. –

+0

私はセマフォーを変更するために解決策を見つけました...セマフォーと "同期"の組み合わせ........ありがとうございました –

答えて

1

これにはjava.util.concurrentタイプのマップを使用できます。スレッドセーフなので、Syncronizeは必要ありません。

同期化:リソース(同期化されている)を複数のスレッドで同時に変更することはできません。 Collections.synchronizedMap(Map)によって返されるMAPは同期マップであり、一度に1つのスレッドで変更できますが、コンカレントコレクションでは、要件に基づいて、複数のスレッドが所定の時間にコレクションの異なる部分にアクセスできます。たとえばConcurentHashMapのオーバーロードされたコンストラクタがあります。ConcurntHashMapは入力concurrencyLevelをコレクションに同時にアクセスできるスレッド数として受け取ります。

+0

2つのスレッドそれらのうちの1つを待たなければならないコレクションを変更しようとしています...しかし、私の場合、2つのスレッドが2つの異なるエントリを変更しようとしている場合、待つべきではありません。 –

+0

Concurrent Collectoinsは同じマップを邪魔するスレッド= P –

+0

2つのスレッドが2つの異なるエントリを取得しようとしている場合、そのうちの1つが正しく待機する必要がありますか? –

関連する問題