2016-12-14 22 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沒有被修改,就可以安全使用。 –