2017-08-16 11 views
0

私は同期マルチマップを持つマルチスレッド環境で作業しています。私はネストされたループでそのマップを使用しており、そのネストされたループ内の各トランザクションの値をクリアしたい。どのようにこれを達成することができます:マルチスレッド環境でネストされたループ内のマップをクリアする

public class Test1 { 
public static void main(String[] args){ 
ExecutorService executor = Executors.newFixedThreadPool(10); 
final Multimap<Object, Object> map = 
Multimaps.synchronizedMultimap(ArrayListMultimap.create()); 

final List<String> listA = new ArrayList<String>(); 
listA.add("e"); 
listA.add("f"); 
listA.add("g"); 
final List<String> listB = new ArrayList<String>(); 
listB.add("e"); 
listB.add("f"); 
listB.add("g"); 
final List<String> listC = new ArrayList<String>(); 
listC.add("e"); 
listC.add("f"); 
listC.add("g"); 


for (final String stateId : listA) { 
    for (final String gradeList : listB) { 
     for (final String subjectList : listC) { 
      executor.execute(new Runnable() { 
       @Override 
       public void run() { 
      map.clear(); 
      map.put("f", "hi"); 
      System.out.println("map before "+map); 

      System.out.println("map after "+map); 
     } 
    }); 
} 

} 
} 
executor.shutdown(); 
try { 
    executor.awaitTermination(24L, TimeUnit.HOURS); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
} 

しかし、これは正しく出力されません。ときには、私は複数の値を見ることができ、時々私はマップを印刷している間に値を見ません。誰でもこの変更を提案できますか?

答えて

1

実行時にすべての操作を同時に実行しています(10回ずつ)。ここではこれらの呼び出し:

 map.clear(); 
     map.put("f", "hi"); 
     System.out.println("map before "+map); 
     System.out.println("map after "+map); 
、f.e.

は、同期ブロックのない一部であり、複数のスレッドからの命令がそれら全体でインターリーブすることができます以下は、スレッドT1およびT2間で有効なインターリーブです:

T1:  map.clear(); 
T2:  map.clear(); 
T1:  map.put("f", "hi"); 
T2:  map.put("f", "hi"); 
T2:  System.out.println("map before "+map); 
T1:  System.out.println("map before "+map); 
T1:  System.out.println("map after "+map); 
T2:  System.out.println("map after "+map); 

私は読者のための練習として、複数の命令間で同期する方法を残しておきます。

+0

はっきりと説明してくれてありがとう。私はマップのための同期ブロックを使用し、魅力のように動作します。完璧な説明をしてくれてありがとう。 :) @ TassosBassoukos – MSR

+0

それは私が探している解決策です。しかし、ここでは同期が重大なパフォーマンス問題を引き起こしています。それは永遠に完了するために必要です。それは約5000のAPI呼び出しとそれが完了するために取る必要があります。これで何か回避策はありますか? – MSR

+0

共有状態を使用しないでください。ロックを保持しているときにネットワークコールを使用しないでください。または、rxjava + retrofitのようなものを使用してください。 –

関連する問題