有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何处理这种多线程场景的问题?

我想做一个分布式系统的模拟,在这个系统中,我应该研究分布式系统中的信息(供应)(如果可以的话,并行!!)例如,我有以下课程:

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

有许多组,每个组都有一个名称,由成员、邻居和供应品的列表组成,每个成员都有一些信息,并向其他组列出可能包含相关信息和供应品的列表,等等

1-我想对供应进行研究,首先:在一个组内,如果我没有找到所需的供应,我应该在与该组相邻的所有组内进行搜索,我想使用多线程进行搜索,我的意思是,如果搜索失败,我应该使用多个线程同时在所有其他邻居中进行搜索,每个线程考虑一个邻居,如果我有10个邻居,那么应该创建10个线程

2-现在,如果我想在第一时间开始几组研究,我的意思是从3或4组或更多组开始,每个组寻找不同的供应,或相同的。。。。 +调用搜索的一个组可能是另一个组的邻居

所以,我的问题是如何使用线程实现这个场景

注:我有一台单处理器单核的机器,我不关心执行时间(开销),我只想模拟这个问题

感谢您的回复,并致以最良好的问候


共 (3) 个答案

  1. # 1 楼答案

    我不认为在单CPU机器上多线程有任何性能优势。这是因为一次只能运行1个线程,并且线程之间会有切换时间,因此实际上可能需要更多的时间才能找到具有所需资源的组

    就我个人而言,我只是遍历第一组的邻居并检查他们的资源。然后,如果没有找到资源,我将调用每个子组的搜索,传入已检查的组列表,这样它就可以跳过已检查的组。比如:

    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;
    }
    

    注意:如果您仍然决定使用多线程,我建议使用一个公共对象来存储所有线程都可以访问的搜索信息。这将指定已检查的组(因此您不会两次检查同一组)以及是否找到所需的供应(因此您可以停止检查资源)

  2. # 2 楼答案

    我无法理解第二个要求,但对于第一个要求,这里有一个可能的方法。但在此之前,从技术上讲,您的进程并不是完全受CPU限制的,它也是受I/O限制的(网络)。因此,请不要假设使其多线程将提供所需的加速你正在寻找。我假设您的开发环境是单处理器和单核,但您的部署环境可能不是

    回到建议上来。我将创建一个GroupPool类,它有一个线程池,可以查找信息。线程数将通过运行时配置参数进行配置。您可以创建一个工厂类,该类从配置文件中读取此参数,并创建一个可运行对象池

    每个对象表示到相邻节点的一个连接。[TODO]您没有提到是否希望在供应商节点上递归,即如果在供应商节点中找不到信息,是否要搜索供应商、供应商的供应商等。如果是这样,您将遇到周期检测问题。一旦这些线程对象搜索并找到信息,它们就会更新factory对象上的信号量(您可能希望将其移动到一个单独的对象,因为这将是一个更好的设计),并发送供应商id(请参阅,单独的对象是有意义的)

    您可以为这个修改过的信号量设置一个侦听器,一旦值发生变化,您就知道找到了您的信息并从该对象获取了供应商id。获得信息后,可以向线程池发送通知,关闭可运行对象,因为您已经找到了信息

    根据您是否正在寻找二进制答案(查找数据,任何供应商都可以),如果您希望递归,上述问题的复杂性将增加

    希望这有助于您尝试为您的问题设计结构

  3. # 3 楼答案

    由于存在CPU受限的问题,因此要使用的最佳线程数可能是您拥有的内核数。我会确保每个线程都有大约100微秒的工作时间,否则你会发现你有比有用的工作更多的超负荷工作。e、 g.您可能会发现搜索10K节点大约需要100个us工作。如果不小心,多线程应用程序可能比单线程应用程序慢很多倍

    因此,我会找到一种方法来划分工作,这样每个线程大约有1K到100K个节点,并将并发性限制在现有的核心数量上