java stream 併發

併發的一個Sream

static void parallelismSum(int n){
        int res = Stream.iterate(1, i -> i+1)
                .limit(n)
                .parallel()
                .reduce(0, Integer::sum);
        System.out.println("parallelismSum res: " + res);
    }

想象中上面的代碼會像下面的圖一樣執行。但實際上不會。因爲iterate函數不支持在stream開始的時候獲取全部元素。
示意圖後一個元素要依賴第一個元素,所以不能在stream開始前獲取全部元素
在這裏插入圖片描述range或者rangeClose函數就可以真正地併發。因爲它可以方便的分割0到n的數組。

static void rangeSum(int n){
        int res = IntStream.rangeClosed(0, n).parallel().reduce(0, Integer::sum);
        System.out.println("RangeSum res: " + res);
    }

算出一段話有幾個單詞
1.狀態類

class WordCount{
    private final int count;
    private final boolean lastWhitespace;

    WordCount(int count, boolean lastWhitespace){
        this.count = count;
        this.lastWhitespace = lastWhitespace;
    }

    public WordCount compute(Character c){
        if(Character.isWhitespace(c)){
            return lastWhitespace? this: new WordCount(count, true);
        }else{
            return lastWhitespace? new WordCount(count+1, false): this;
        }
    }

    public WordCount combine(WordCount wordCount){
        return new WordCount(count + wordCount.getCount(), lastWhitespace);
    }

    public int getCount(){
        return count;
    }
}

2.分割器

public class MySpliterator implements Spliterator<Character> {

    private final String article;
    private int currentIndex;

    private static final int THRESHOLD = 30;

    MySpliterator(final String article){
        this.article = article;
        this.currentIndex = 0;
    }

    @Override
    public boolean tryAdvance(Consumer<? super Character> action) {
        action.accept(article.charAt(currentIndex));
        currentIndex++;
        return currentIndex < article.length();
    }

    @Override
    public Spliterator<Character> trySplit() {
        int currentSize = article.length() - currentIndex;
        if(currentSize <= THRESHOLD){
            return null;
        }
        for(int midIndex = currentSize/2 + currentIndex; midIndex < article.length();
            midIndex++){
            if(!Character.isWhitespace(article.charAt(midIndex))){
                continue;
            }
            MySpliterator mySpliterator = new MySpliterator(article.substring(currentIndex, midIndex));
            currentIndex = midIndex;
            return mySpliterator;
        }
        return null;
    }

    @Override
    public long estimateSize() {
        return article.length() - currentIndex;
    }

    @Override
    public int characteristics() {
        return ORDERED + SIZED + SUBSIZED + NONNULL + IMMUTABLE;
    }

}

3.測試用例

    public static void main(String[] args) {
        Spliterator<Character> spliterator = new MySpliterator(article);
        Stream<Character> stream =StreamSupport.stream(spliterator, true);
        WordCount wordCount = stream.reduce(new WordCount(0, true), WordCount::compute, WordCount::combine);
        System.out.println(wordCount.getCount());
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章