2013-04-11 162 views
2

我試圖在列表中添加一些項目並保留添加順序。問題是 的添加部分是在一個線程中完成的,因爲我需要從DB獲得一些細節,將它們放在
項目中並將其添加到列表中。如何將項目添加到線程列表中並保持添加順序?

public void addNewItem(Step item){ 

    Thread t = new Thread(new Runnable(){ 
     public void run() { 
      item.setDetails(db.getStepDetails(step.getId())); 
      add(item); 
     } 
    }); 

    t.start(); 
} 

add方法是這樣的:

private void add(Step step){ 
    mitems.add(step); 
} 

如果我這樣做

addNewItem(stepA); 
addNewItem(stepB); 

如果第一次調用花費太多時間,第二項是第一次在我的名單中添加。

您是否知道在我的列表中繼續添加任何其他項目之前,我該如何等待某個操作完成?

謝謝。

+0

我可能是錯的,但我相信使用'synchronize'可以解決這個問題 – codeMagic 2013-04-11 12:44:13

+1

你真的想用一個單獨的線程?在你的情況下,你需要按順序執行指令。 – blint 2013-04-11 12:46:11

+0

解決方法是一個同步的ID,每次添加時都會增加並存儲在添加的項目中。然後,您可以在結果容器中看到添加項目的順序。 – TheBlastOne 2013-04-11 12:46:29

回答

0

您可以添加同步塊或使用ReentrantLock。

Thread t = new Thread(new Runnable(){ 
    public void run() { 
     synchronized(someSafeVar) { 
      item.setDetails(db.getStepDetails(step.getId())); 
      add(item); 
     } 
    } 
}); 

此外,如果只是需要時間的「添加」方法,則此方法只能同步。

0

如果您將物品添加到清單之前您設置的詳細信息,您可以保留您的物品訂單。 那麼你可以用隨後的所有操作等到你的項目的初始化標誌設置:

mitems.add(stepA); 
mitems.add(stepB) 

[...] 

ThreadGroup group = new ThreadGroup("GetStepDetailsGroup"); 

for(Step step : mitems) 
{ 
    Thread thread = new Thread(group, new Runnable(){ 
     public void run() { 
      item.setDetails(db.getStepDetails(step.getId())); 
     } 
    }); 

    thread.start(); 
} 

while(group.activeCount() > 0) { 
    try { 
     Thread.sleep(50); 
    } catch(InteruptedExpection e) { 
     // ignored 
    } 
} 
0

您可以創建一個工作線程,並從隊列中餵養它,這樣的話你將有一個單獨的線程加入到mitems。

您需要在這種情況下創建兩個列表,並同步它們。

EG,

List<Step> processingList = new ArrayList<Step>(); 
List<Step> mitems = new ArrayList<Step>(); 
public void addNewItem(Step item) 
{ 
    syncrhonized(processingList) 
    { 
    processingList.add(item); 
    } 
} 

工作者線程需要的物品從processingList的前面,適用於他們,並將他們時,他們已經準備好mitems。

+0

我建議使用隊列作爲processingList,因爲將項添加到最後並從頭開始檢索它們對於隊列工作來說是典型的 – 2013-04-11 12:56:17

0

你可以使用一個字典來代替:

Dictionary mitems = new Hashtable(); 

mitems.put("1", item); 

的關鍵將是命令即可。

0

在您的示例中,它看起來像將列表中的步驟添加到完全獨立於從數據庫檢索信息並填寫步驟。

因此,您可以只使用一個線程將所有步驟放入列表中。然後,您可以使用Runnables獲取數據庫信息,每個步驟一個,並在Executor中執行這些Runnable,並使用盡可能多的線程(同時仍然從多線程獲得加速)。

0

Thread#join

等待該線程死亡。

希望這有助於 亞龍

+0

如何知道「線程死了?」 – LomE999 2014-08-21 04:09:45