2013-01-17 65 views
0

我正在研究多线程程序,其中每个线程都计算两个数字的GCD,将数字和GCD存储到TreeMap中,并在所有线程完成后打印出TreeMap。我应该使用什么样的方法来确保只有一个线程同时存储数据,以及如何使用最后一个线程在准备好打印时打印TreeMapJava中的多线程和同步

for (int i = 0; i < myList.size(); ++i) { 
    for (int j = i + 1; j < myList.size(); ++j) { 
     modulus1 = myList.get(i); 
     modulus2 = myList.get(j); 
     pool.execute(new ThreadProcessRunnable(modulus1, modulus2, myMap)); 
    } 
} 

public void run() { 
    ThreadProcess process = null; 
    try { 
     // Only one thread should execute the following code 
     for (Map.Entry<BigInteger, ArrayList<BigInteger>> entry : myMap.entrySet()) { 
      System.out.println("key ->" + entry.getKey() + ", value->" + entry.getValue()); 
     } 
    } catch (Exception e) { 
     System.err.println("Exception ERROR"); 
    } 
+0

[Synchronize](http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)访问数据的方法 – paulsm4

+0

看起来您的'for'循环应该只是一个'if'检查? 'List list = myMap.get(FirstModulus); if(list == null){list = new ArrayList (); myMap.put(FirstModulus,list); } list.add(gcd);'(这消除了对'if(myMap.size()> 0){...} else {...}'的需要,并且使它更可读) – pickypg

+0

有一个看看这样的线程沟通讨论http://stackoverflow.com/questions/12274821/using-a-static-var-in-a-thread-as-communication-among-different-instances – pickypg

回答

0
  //Only one thread should executes the following code 
synchronize{    
for (Map.Entry<BigInteger, ArrayList<BigInteger>> entry : myMap.entrySet()) { 
       System.out.println("key ->" + entry.getKey() + ", value->" + entry.getValue()); 
      } 
} 
1

你必须使用你需要保证地图单个线程访问的地方syncronize(myMap) {...}块。

至于打印最后一个线程的结果,可以使用布尔标志作为完整性的信号,并且每次检查它。不要忘了让它volatile让每个线程看到它的价值变化。

UPD: Brian Goetz“Java Concurrency In Practice”是强烈推荐的阅读。

+0

谢谢。布尔标志在每个线程内工作?应该在哪里检查条件? – John

0

您可以使用Collections.synchronizedMap使其线程安全。并且使用thread.join来确保只有当所有线程都死了时才能进行打印。

编辑:在主线程中进行打印。在印刷之前,请在所有主题上致电join

+0

同样的问题与Quoi的解决方案有关。 – pickypg

+0

加入等待线程死亡。我怎么知道所有线程何时完成。 – John