簡體   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