繁体   English   中英

递归并发

[英]Recursive concurrency

我具有以下伪代码功能:

Result calc(Data data) {
  if (data.isFinal()) {
    return new Result(data); // This is the actual lengthy calculation
  } else {
    List<Result> results = new ArrayList<Result>();
    for (int i=0; i<data.numOfSubTasks(); ++i) {
      results.add(calc(data.subTask(i));
    }
    return new Result(results); // merge all results in to a single result
  }
}

我想使用固定数量的线程对其进行并行化。

我的第一次尝试是:

ExecutorService executorService = Executors.newFixedThreadPool(numOfThreads);

Result calc(Data data) {
  if (data.isFinal()) {
    return new Result(data); // This is the actual lengthy calculation
  } else {
    List<Result> results = new ArrayList<Result>();
    List<Callable<Void>> callables = new ArrayList<Callable<Void>>();
    for (int i=0; i<data.numOfSubTasks(); ++i) {
      callables.add(new Callable<Void>() {
        public Void call() {
         results.add(calc(data.subTask(i));
        }
      });
    }
    executorService.invokeAll(callables);  // wait for all sub-tasks to complete
    return new Result(results); // merge all results in to a single result
  }
}

但是,这很快陷入了僵局,因为,当顶级递归级别等待所有线程完成时,内部递归级别也等待线程变得可用...

如何有效地并行化程序而不会出现死锁?

当您将ThreadPoolExecutor用于具有依赖项的任务时,您的问题是一个常规设计问题。

我看到两个选择:

1)确保以自下而上的顺序提交任务,这样您就永远不会有依赖于尚未开始的任务的正在运行的任务。

2)使用“直接切换”策略(请参阅ThreadPoolExecutor文档):

ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, poolSize, 0, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
executor.setRejectedExecutionHandler(new CallerRunsPolicy());

这个想法是使用同步队列,以便任务永远不会在真实队列中等待。 拒绝处理程序负责没有可用线程运行的任务。 使用此特定处理程序,提交者线程将运行被拒绝的任务。

此执行程序配置可确保任务永不被拒绝,并且由于任务间的依赖性而不会出现死锁。

您应该将方法分为两个阶段:

  1. 创建所有树直到data.isFinal()== true
  2. 递归收集结果(仅在合并不产生其他操作/调用的情况下才可能)

为此,您可以使用[Futures][1]使结果异步。 表示calc的所有结果均为Future [Result]类型。

立即返回一个Future将释放当前线程并为其他线程的处理留出空间。 使用结果集(新的结果(结果)),您应该等待所有结果准备就绪(ScatterGather-Pattern,您可以使用信号量等待所有结果)。 集合本身将走一棵树,并在单个线程中进行检查(或等待结果到达)。

总体而言,您会构建一棵期货树,该树用于收集结果并仅在线程池中执行“昂贵”的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM