0

我有一个需要按特定顺序执行的任务列表,例如 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);}

}

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

//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

} //尽管

Task 类扩展了 Thread 类,每个 Task 都有一个 inEdges 和 outEdges 的 HashSet。我应该如何处理?

4

1 回答 1

0

你期待多少任务?有几种方法可以解决这个问题。我会选择在总处理时间内优化代码的可读性和可维护性,因此我会推荐以下内容。

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

  1. 创建一个算法,该算法接受一组任务并将它们汇总到彼此独立的任务中。例如,如果您有任务 A、B、C,其中 A 依赖于 B,但没有其他依赖项,那么您的算法应该返回两个“汇总”任务。一个用于“B 然后 A”,另一个用于 C。此外,如果 A 依赖于 C 而 B 依赖于 C,那么它们将被汇总到同一个任务中(这是性能不是最佳的地方)。
  2. 现在,您拥有了一组可以彼此独立运行的汇总任务。使用任意数量的线程启动 ThreadPoolExecutor。
  3. 对于每个汇总的任务,创建一个 Runnable,它将以适当的顺序运行子任务。将每个任务提交给执行者。
于 2013-09-26T05:29:38.667 回答