2016-12-14 23 views
0

我刚开始学习线程背后的概念,我被困在一个问题上。当场运行多个线程,等待所有完成,方便和安全hashMap

我有一个​​阵列,N是可变的,但总是<= 5。 我有另一个空阵列,容量为N

现在,我必须对每个字符串one by one进行一些复杂的计算,并且每个结果都放在空数组中,与刚刚检查的字符串具有相同的索引。

当一切都结束时,分析结果数组并保留最长的结果。所有这些正在发生的线程是主线程。

这个计算需要很多时间,所以我在想是否值得它打开N新线程,并且将它们全部评估在一起。

值得一提的是计算涉及查找HashMap<String, customObject>上的字符串,这对所有的字符都是一样的。因此,使用线程,他们将一起访问它。他们不会编辑它,只需查找值。该地图可以更改,但从不执行此操作,因为它稍后会在主线程中从代码中的其他部分更改。

例子:

//Current approach 

HashMap<String, Object> m = new HashMap<>(); //filled with 10^6 values 

String[] data = new String[3]; 
Object[] results = new String[3]; 

results[0] = complexCalculationsAndSearcOnHashMap(data[0]); 
results[1] = similarComplexCalculationsAndSearcOnHashMap(data[1]); 
results[2] = otherComplexCalculationsAndSearcOnHashMap(data[2]); 

//Now every complex calculation has to wait until the last one ended before starting. But the only thing that actually should have to wait is this next line: 

Object finalResult = longest(results); 

所以我的问题是,我应该建立3个线程,把复杂的计算中的run方法?方便吗,还是我弄错了整个线程概念?这在应用程序中造成了瓶颈,完成需要很长时间。

例如用螺纹:

HashMap<String, Object> m = new HashMap<>(); //filled with 10^6 values 

    String[] data = new String[3]; 
    Object[] results = new String[3]; 

    Thread t0 = new Thread(){ 

    public void run(){ 
     results[0] = complexCalculationsAndSearcOnHashMap(data[0]); 
    } 
}; 

//Thread t1, t2.. 
//t0.start(), t1.start()... 

Object finalResult = longest(results); 

如果前面的答案是肯定的,我怎么最后一行等待所有3个线程来完成,而他们跑独立海誓山盟的? 我是否加入了3个循环?

最后但并非最不重要,是否安全使用HashMap的方式?
或者我应该切换到另一个更适合线程的集合对象? 我已阅读了几个想法,没有人似乎同意。 会慢吗?我不能失去任何优化,除非现在非常需要。

编辑:

应当指出的是,“他们需要很长的时间才能完成”不应该被认为是理所当然的。虽然97%的时间N功能需要很长时间才能完成,但可能发生的几乎是瞬间的。 我不知道这是否有所作为。

**编辑2:**

我不仅问如何运行的所有4个,并等待他们完成,我还需要知道,如果它是在这种情况下,或者做正确的事它不会改变一件事情,另外我需要了解是否可以使用hashMap。

**细节上的代码**

  • 所有这一切都在同一对象内发生,无静电场被使用过。
  • 在另一个对象中,HashMap早已被初始化。
  • HashMap可以更改,但在另一个对象中,在同一个线程上。所以在其他3个线程运行时不会发生。
  • 这是应用程序使用更多线程的唯一时间。
+0

可能重复的[如何等待所有线程完成,使用ExecutorService?](http://stackoverflow.com/questions/1250643/how-to-wait-for-all-threads-to-finish-using -executorservice) –

+0

关于重复 - 描述如何使用Future的答案是最干净的IMO,但所有答案都为您提供了一个解决方案。 –

+0

*“...使用HashMap是否安全?” - 这取决于你在何处以及如何初始化地图。事实上,这很多方面将取决于你的代码的确切细节。 –

回答

3

您可以使用简单的方法,并为每一个“计算”你有

Thread[] workers = new Thread[count]; 
    for (int i = 0; i < count; i++) { 
     final int index = i; 
     //create thread to calculate i-th value 
     workers[i] = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       results[index] = complexCalculationsAndSearcOnHashMap(data[index]); 
      } 
     }); 
     workers[i].start(); 
    } 
    for (int i = 0; i < count; i++) { 
     //wait until threads execution is finished 
     workers[i].join(); 
    } 

    //Test output 
    System.out.println(Arrays.toString(results)); 

如果你的计算功能取决于索引创建主题...你可以选择使用索引相应的功能或创建线程在循环之外。

+0

这样哈希映射是否安全? –

+0

只要'计算'线程运行时HashMap没有被修改,就可以安全使用。 –