1

我有一个嵌套for循环的方法,如下所示:

public MinSpecSetFamily getMinDomSpecSets() throws InterruptedException {
    MinSpecSetFamily result = new MinSpecSetFamily();
    ResourceType minRT = this.getFirstEssentialResourceType();
    if (minRT == null || minRT.noSpecies()) {
        System.out.println("There is something wrong with the "
                + "minimal rticator, such as adjacent to no species. ");
    }
    for (Species spec : minRT.specList) {
        ArrayList<SpecTreeNode> leafList = this.getMinimalConstSpecTreeRootedAt(spec).getLeaves();
        for (SpecTreeNode leaf : leafList) {
            result.addSpecSet(new SpecSet(leaf.getAncestors()));
        }
    }
    return result;
}

这很好用,但应用程序对性能至关重要,所以我修改了使用方法parallelStream(),如下所示:

public MinSpecSetFamily getMinDomSpecSets() throws InterruptedException {
    ResourceType minRT = this.getFirstEssentialResourceType();
    if (minRT == null || minRT.noSpecies()) {
        System.out.println("There is something wrong with the "
                + "minimal rticator, such as adjacent to no species. ");
    }

    MinSpecSetFamily result = minRT.specList.parallelStream()
            .flatMap(spec -> getMinimalConstSpecTreeRootedAt(spec).getLeaves().parallelStream())
            .map(leaf -> new SpecSet(leaf.getAncestors()))
            .collect(MinSpecSetFamily::new, MinSpecSetFamily::addSpecSet, MinSpecSetFamily::addMSSF);
    return result;
}

这工作得很好,直到我想InterruptedException在“getLeaves()”方法中引入一个。现在该parallelStream版本将无法编译,因为它说我有一个未报告InterruptedException的必须被捕获或声明为被抛出。我认为这是因为parallelStream在多个线程上运行。我的 IDE 建议的 try/catch 块的组合无法解决此问题。

在中断并行流执行中发布的第二个解决方案 表明我可以使用解决问题,ForkJoinPool但我一直无法弄清楚如何修改我的方法以使用这种方法。

4

1 回答 1

2

如果你想坚持你当前的设计,你只需要捕获异常:

.flatMap(spec -> {
     try {
       return getMinimalConstSpecTreeRootedAt(spec).getLeaves().parallelStream();
     } catch (InterruptedException e) {
       // return something else to indicate interruption
       // maybe an empty stream?
     }
 }).map(...)

请注意,并行流的并行流可能是不必要的,仅并行化顶级流在性能方面可能就足够了。

于 2018-02-15T10:12:17.050 回答