Java 使用线程执行TopSorted列表

Java 使用线程执行TopSorted列表,java,multithreading,topological-sort,Java,Multithreading,Topological Sort,我有一个需要按特定顺序执行的任务列表,例如Task2->Task1,因此必须先执行Task1,然后才能运行Task2。我已经构建了一个任务图,并应用了拓扑排序来获得任务执行的顺序,但现在我想使用线程abd执行这些任务,这就是我遇到的问题。这是我到目前为止所做的 //S = Hashset that contains tasks that has no input edges in graph public HashSet<Task> S = new HashSet<Task&g

我有一个需要按特定顺序执行的任务列表,例如Task2->Task1,因此必须先执行Task1,然后才能运行Task2。我已经构建了一个任务图,并应用了拓扑排序来获得任务执行的顺序,但现在我想使用线程abd执行这些任务,这就是我遇到的问题。这是我到目前为止所做的

//S = Hashset that contains tasks that has no input edges in graph
public HashSet<Task> S = new HashSet<Task> ();
for(Task n : AllTasks){ //AllTasks is an arraylist of tasks in graph
if(n.inEdges.size() == 0){
 S.add(n);}
//S=Hashset,其中包含在图形中没有输入边的任务
公共HashSet S=新HashSet();
for(Task n:AllTasks){//AllTasks是图中任务的数组列表
如果(n.inEdges.size()==0){
S.add(n);}
}

//将包含已排序元素的空列表 ArrayList outList=新的ArrayList()

//当S为非空do时
而(!G.S.isEmpty()){
//从S中删除节点n
任务n=G.S.迭代器().next();
G.S.remove(n);
//在L中插入n
添加(n);
n、 start();//启动线程
//对于每个节点m,边e从n到m do
for(Iterator it=n.outEdges.Iterator();it.hasNext();){
//从图形中删除边e
边e=it.next();
任务m=e.to;
it.remove();//从n中删除边
m、 inEdges.remove(e);//从m中删除边
//如果m没有其他传入边,则将m插入S
if(m.inEdges.isEmpty()){
G.S.add(m);
}//如果
}//为了
}//而


Task类扩展了Thread类,每个任务都有一组InEdge和OutEdge。我应该如何处理它?

您希望完成多少任务?有几种方法可以做到这一点。我会选择在整个处理时间内优化代码的可读性和可维护性,因此我建议如下

让任务扩展线程可能不是一个好办法。如果您有足够的任务,您将发现自己无法生成足够的线程。您的任务类应该反映您的问题域(例如,作业相关性)。已经有一组类可以很好地处理并发问题域(Executor框架)。通过以这种方式构造类,您可以轻松地从多线程实现切换到多进程实现。这就是我构建解决方案的方式

  • 创建一个算法,该算法接受一组任务,并将它们汇总到相互独立的任务中。例如,如果您有任务A、B、C,其中A依赖于B,但没有其他依赖项,那么您的算法应该返回两个“汇总”任务。一个用于“B,然后是A”,另一个用于C。同样,如果A依赖于C,而B依赖于C,那么它们将被汇总到同一个任务中(这是性能不是最佳的)
  • 现在,您有了一组可以彼此独立运行的汇总任务。启动一个ThreadPoolExecutor,其中包含您想要的任意多个线程
  • 对于每个汇总任务,创建一个Runnable,它将以适当的顺序运行子任务。将每个任务提交给执行者

  • 您的解决方案可能是一个很好的解决方案(就性能而言),但我现在的解决方案已经差不多完成了,只需要在其中集成并发性,所以只需尝试在该领域寻找可能性。无论如何,谢谢你,因为我想到了不同的算法。干杯
    //while S is non-empty do
    while(!G.S.isEmpty()){
      //remove a node n from S
        Task n = G.S.iterator().next();
      G.S.remove(n);
      //insert n into L
      outList.add(n);
    
      n.start(); //Starts the thread
    
      //for each node m with an edge e from n to m do
      for(Iterator<Edge> it = n.outEdges.iterator();it.hasNext();){
        //remove edge e from the graph
        Edge e = it.next();
        Task m = e.to;
        it.remove();//Remove edge from n
        m.inEdges.remove(e);//Remove edge from m
    
        //if m has no other incoming edges then insert m into S
        if(m.inEdges.isEmpty()){
        G.S.add(m);
        }//if
      }//for