我想执行一个流,然后在同一个操作中将流的输出用作同一个流的源。
我目前使用队列执行此类操作;我删除一个项目,处理它,并将需要进一步处理的任何结果添加回队列。以下是这类事情的两个例子:
Queue<WorkItem> workQueue = new Queue<>(workToDo);
while(!workQueue.isEmpty()){
WorkItem item = workQueue.remove();
item.doOneWorkUnit();
if(!item.isDone()) workQueue.add(item);
}
Queue<Node> nodes = new Queue<>(rootNodes);
while(!nodesLeft.isEmpty()){
Node node = nodes.remove();
process(node);
nodes.addAll(node.children());
}
我认为第一个可以同时执行:
try {
LinkedBlockingQueue<WorkItem> workQueue = new LinkedBlockingQueue<>();
Stream<WorkItem> reprocess = Stream.generate(() -> workQueue.remove()).parallel();
Stream.concat(workToDo.parallelstream(), reprocess)
.filter(item -> {item.doOneWorkUnit(); return !item.isDone();})
.collect(Collectors.toCollection(() -> workQueue));
} catch (NoSuchElementException e){}
第二个:
try {
LinkedBlockingQueue<Node> reprocessQueue = new LinkedBlockingQueue<>();
Stream<WorkItem> reprocess = Stream.generate(() -> nodes.remove()).parallel();
Stream.concat(rootNodes.parallelStream(), reprocess)
.filter(item -> {process(item); return true;})
.flatMap(node -> node.children().parallelStream())
.collect(Collectors.toCollection(() -> reprocessQueue));
} catch (NoSuchElementException e){}
然而,这些感觉就像kludgy的变通方法,我不喜欢不得不求助于使用异常。有没有人有更好的方法来做这类事情?
答案 0 :(得分:1)
为了使工作平行,我会使用标准java.util.concurrent.Executor
。要将任务返回到工作队列,请在每个任务的代码末尾添加executor.execute(this)
。