繁体   English   中英

如何在Java中并行化循环

[英]How to parallelize a loop in Java

在以下代码中,在HashSet的每个元素上调用一个本地方法。 如果返回一个特殊值,我们将停止循环。 否则,我们将每个返回值添加到新的HashSet中。

HashSet<Object> myHashSet=…; 
HashSet<Object> mySecondHashSet=…; 

for (Object s : myHashSet) {
    Object value = my_method(s);
    if(value==specialValue)
        return value; 
    else 
        mySecondHashSet.add(value);
 }

我想将这个过程并行化。 HashSet中的所有对象都没有任何共同的对象(这是树状结构),因此我知道它们可以运行而没有任何同步问题。 如何修改代码,使my_method的每次调用开始一个新的过渡,并且如果一个线程的求值结果为特殊值,则所有线程都将暂停而不返回,并返回特殊值?

考虑到Java 8,这可能相对简单,但它不会保留您的初始代码语义:

万一您需要击中返回特殊值

if (myHashSet.parallelStream()
             .map(x -> method(x))
             .anyMatch(x -> x == specialValue)) {

    return specialValue;
}

如果您需要保持转换后的值直到满足特殊值,您已经从@Elliot的注释中得到了答案,同时需要提及的是语义与原始代码不同,因为将不保留任何定序符。


虽然尚待检查,但我希望可以优化以下内容,并在达到所需的特殊值时停止:

if (myHashSet.parallelStream()
             .anyMatch(x -> method(x) == specialValue)) {

    return specialValue;
}

我会分两步这样做:

  1. 查找是否有任何变换后的set元素与特殊值匹配;
  2. 将它们转换为集合。

为每个转换启动一个新线程太重了,并且会使您的机器瘫痪(除非您只有很少的元素,在这种情况下,并行化可能不值得付出努力。

为了避免使用my_method两次转换值,您可以延迟进行转换并记住结果:

private class Memoized {
    private Object value;
    private Object transformed;
    private Function<Object, Object> transform;

    public Memoized(Object value, Function<Object, Object> transform) {
        this.value = value;
    }

    public Object getTransformed() {
        if (transformed == null) {
            transformed = transform.apply(value);
        }
        return transformed;
    }
}

然后可以使用以下代码:

Set<Memoized> memoizeds = 
    myHashSet.stream() // no need to go parallel here
             .map(o -> new Memoized(o, this::my_method))
             .collect(Collectors.toSet());

Optional<Memoized> matching = memoized.parallelStream()
    .filter(m -> m.getTransformed().equals(specialValue))
    .findAny();

if (matching.isPresent()) {
    return matching.get().getTransformed();
}

Set<Object> allTransformed = 
    memoized.parallelStream() 
            .map(m -> m.getTransformed())
            .collect(Collectors.toSet());

暂无
暂无

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

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