Java11从8个并行流升级引发classnotfoundexception

wsewodh2  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(533)

我将我的spring-boot应用程序从java8和tomcat8升级到java11和tomcat9。除了我在列表中使用并行流的部分之外,一切似乎都很好。

list.addAll(items
                .parallelStream()
                .filter(item -> !SomeFilter.isOk(item.getId()))
                .map(logic::getSubItem)
                .collect(Collectors.toList()));

前一部分代码使用java8和tomcat8时工作正常,但在java9更改了fork/join公共池如何加载类之后,线程返回系统类装入器作为其线程上下文类装入器。
我知道在后台并行流使用forkjoinpool,我创建了一个自定义bean类,但是应用程序仍然没有使用它。很可能是因为它们可能是在这个bean之前创建的。

@Bean
public ForkJoinPool myForkJoinPool() {
    return new ForkJoinPool(threadPoolSize, makeFactory("APP"), null, false);
}

private ForkJoinPool.ForkJoinWorkerThreadFactory makeFactory(String prefix) {
    return pool -> {
        final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
        worker.setName(prefix + worker.getPoolIndex());
        worker.setContextClassLoader(Application.class.getClassLoader());
        return worker;
    };
}

最后,我还尝试将它 Package 到forkjoinpool的一个示例中,但它是异步完成的,我不想这样做。我也不想使用submit和get,因为这意味着我必须用try/catch来 Package 我在应用程序上的所有并行流,代码读起来会很难看。

forkJoinPool.execute(() -> 
  list.addAll(items
                .parallelStream()
                .filter(item -> !SomeFilter.isOk(item.getId()))
                .map(logic::getSubItem)
                .collect(Collectors.toList())));

理想情况下,我希望应用程序中使用的所有并行流都使用来自应用程序的类装入器,而不是系统装入器。
你知道吗?

dkqlctbz

dkqlctbz1#

如果选择使用第三方,则可以使用并行收集器库:

list.addAll(items
            .stream()
            .filter(item -> !SomeFilter.isOk(item.getId()))
            .collect(parallel(logic::getSubItem, Collectors.toList(), forkJoinPool)
            .join());

相关问题