2011-05-16 26 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; 
} 

注意:如果你仍然决定去的多线程,我建议存储有关的所有线程访问的搜索信息的公共对象。这将指定已检查的组(因此您不检查相同的组两次)以及是否找到所需的耗材(以便您可以停止检查资源)。