2011-05-16 33 views
1

我想模擬一個分佈式系統,其中,我應該在分佈式(如果我可以!!)方式下對信息(耗材)進行研究,例如我有以下類:如何多線程這個問題的場景?

public class Group{ 
public int identifier; 
public int[] members; 
public String name; 
public String[] supplies; 
public int[] neighbors;} 

有許多團體,每個人都有一個名字,由成員,鄰居和物資清單中,每個成員都有一些信息,並列出可能含有相關信息及耗材等其他羣體。

1-我想對耗材進行研究,首先:在一個團隊內部,如果我找不到所需的耗材,我應該在這個團隊的鄰居組中進行搜索,我認爲要做這是使用多線程,我的意思是,如果搜索失敗,我應該使用多個線程同時在所有其他鄰居內進行搜索,每個線程考慮一個鄰居,如果我有10個鄰居,則應該有10個線程創建....

2-現在,如果我想在第一次開始重新搜索與幾個組,我的意思是開始3或4組或更多,每個尋找一個不同的供應,或相同.... +調用搜索的一個組可能是另一個組的鄰居...

所以,我的問題是如何使用線程實現這種情況?

PS.I有一臺機器與一個核心的單一處理器,並且我不在乎執行(開銷)的時間,我要的就是模擬這個問題...

感謝每一個迴應,最好的問候。

回答

1

由於您遇到了CPU綁定問題,因此使用的最佳線程數可能是您擁有的核心數。我會確保每個線程都有大約100微秒的工作量,否則你會發現你比有用的工作更有價值。例如你可能會發現搜索10K節點大概是100 us的工作。如果你不小心,多線程應用程序可能比單線程應用程序慢很多倍。

因此,我會找到一種方法來分配工作,以便每個線程擁有大約1K到100K個節點,並將您的併發數限制爲您擁有的核心數。

+0

謝謝,但我不在乎執行時間(開銷),我只想要模擬這個問題... – jojo 2011-05-16 18:07:51

+0

我會創建一個ExecutorService與執行程序並提交任務給它做你需要的。我會使用newSingleThreadExecutor()來獲得最佳性能。 – 2011-05-16 18:10:06

1

我不明白第二個要求,但對於第一個,這裏是一個可能的方法。但在此之前,從技術上講,您的過程並不完全受CPU限制,它也是I/O綁定(網絡)。所以,請不要認爲使它多線程將提供您所需要的加速。我假設您的開發環境是單處理器和單核,但您的部署環境可能不是。

返回建議。我將創建一個GroupPool類,該類有一個線程池,可以偵測信息。線程數量可通過運行時配置參數進行配置。您可以創建一個工廠類,它從配置文件讀取此參數並創建一個可運行對象池。

這些對象中的每一個都表示到相鄰節點的一個連接。 [TODO]你沒有提到你是否願意在供應商節點上遞減,即如果你沒有在供應商節點找到信息,你是否想要搜索供應商,供應商的供應商等。如果是這樣,你會有周期檢測的問題。一旦這些線程對象偵察到信息並找到它,它們會更新工廠對象上的信號量(您可能希望將其移至單獨的對象,因爲這會是更好的設計),並且還會發送供應商ID(請參閱單獨的對象有一定道理)

你可以有一個監聽這個修改信號並儘快價值的變化,你知道你發現你的資料,並從該對象的供應商ID。一旦獲得了您的信息,您就可以向線程池發送通知,以便在您已經找到您的信息時關閉可運行對象。基於

您是否正在尋找一個二進制的答案(發現數據和任何供應商是確定的),如果你想遞歸的上述複雜性會增加。

希望這有助於你試圖爲你的問題設計結構。

1

我沒有看到任何性能優勢,多線程這在單個CPU機器上。這是因爲一次只能運行一個線程,線程之間會有切換時間,因此實際上可能需要更多時間才能找到具有所需資源的組。

就個人而言,我只是通過第一組的鄰國進行迭代,並檢查他們的資源。然後,如果沒有找到的資源,我會打電話給在每個子組的搜索,傳遞已經檢查了組的列表,所以它可以跳過那些已經被檢查組。喜歡的東西:

public Group searchForGroupWithResource(Resource resource){ 
    List<Group> groupsToCheck = new ArrayList<Group>(); 
    groupsToCheck.add(this); 
    int currentIndex = 0; 
    while(currentIndex < groupsToCheck.size()){ 
     Group currentGroup = groupsToCheck.get(currentIndex); 
     if(currentGroup.hasResource(resource)){ 
      return currentGroup; 
     } 
     groupsToCheck.addAll(currentGroup.getNeighbors(groupsToCheck)); 
     currentIndex++; 
    } 
    return null; 
} 

public List<Group> getNeighbors(List<Group> excludeGroups){ 
    //Get non-excluded neighbors 
    List<Group> returnNeighbors = new ArrayList<Group>(); 
    for(Group neighbor : neighbors){ 
     boolean includeGroup = true; 
     for(Group excludeGroup : excludeGroups){ 
      if(excludeGroup.equals(neighbor)){ 
       includeGroup = false; 
       break; 
      } 
     } 
     if(includeGroup){ 
      returnNeighbors.add(neighbor); 
     } 
    } 
    return returnNeighbors; 
} 

注意:如果你仍然決定去的多線程,我建議存儲有關的所有線程訪問的搜索信息的公共對象。這將指定已檢查的組(因此您不檢查相同的組兩次)以及是否找到所需的耗材(以便您可以停止檢查資源)。