简体   繁体   English

如何在Java Stream的单个步骤中使用并行执行

[英]How can I use parallel execution on a single step of a Java Stream

I am performing a single expensive operation in my stream manipulation which I would like to multithread, but remaining operations should be single threaded. 我在我的流操作中执行一个昂贵的操作,我想多线程,但剩余的操作应该是单线程的。 For example: 例如:

package test;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.IntStream;

public class TestStreams {
    private static Set<String> expensiveThreads = ConcurrentHashMap.newKeySet();
    private static Set<String> cheapThreads = ConcurrentHashMap.newKeySet();

    public static void main(String[] args) {
        IntStream.range(1, 1000).parallel().map(i -> myExpensiveMap(i))
                .unparallel()  //does not compile
                .forEach(i -> myCheapOperation(i));
        System.out.println("Expensive Threads:" + expensiveThreads);
        System.out.println("Cheap Threads:    " + cheapThreads);
    }

    private static void myCheapOperation(int i) {
        cheapThreads.add(Thread.currentThread().getName());
    }

    private static int myExpensiveMap(int i) {
        expensiveThreads.add(Thread.currentThread().getName());
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return i;
    }
}

The current output is: 目前的输出是:

Expensive Threads:[ForkJoinPool.commonPool-worker-1, ForkJoinPool.commonPool-worker-2, main, ForkJoinPool.commonPool-worker-3]
Cheap Threads:    [ForkJoinPool.commonPool-worker-1, ForkJoinPool.commonPool-worker-2, main, ForkJoinPool.commonPool-worker-3]

But the output I would like is: 但我想要的输出是:

Expensive Threads:[ForkJoinPool.commonPool-worker-1, ForkJoinPool.commonPool-worker-2, main, ForkJoinPool.commonPool-worker-3]
Cheap Threads:    [main]

I have tried wrapping the original stream using StreamSupport(Spliterator, false), but this limits the original stream to single thread processing. 我尝试使用StreamSupport(Spliterator,false)包装原始流,但这会将原始流限制为单线程处理。 For example: 例如:

StreamSupport.stream(
                IntStream.range(1, 1000).parallel().map(i -> myExpensiveMap(i))
                        .spliterator(), false)
                .forEach(i -> myCheapOperation(i));

Expensive Threads:[main]
Cheap Threads:    [main]

Or using parallel = true, for example: 或者使用parallel = true,例如:

StreamSupport.stream(
                IntStream.range(1, 1000).parallel().map(i -> myExpensiveMap(i))
                        .spliterator(), true)
                .forEach(i -> myCheapOperation(i));

Expensive Threads:[ForkJoinPool.commonPool-worker-1, ForkJoinPool.commonPool-worker-2, main, ForkJoinPool.commonPool-worker-3]
Cheap Threads:    [ForkJoinPool.commonPool-worker-1, ForkJoinPool.commonPool-worker-2, main, ForkJoinPool.commonPool-worker-3]

How can I unparallel this Stream? 我怎么能无法平行这个流?

The opposite of .parallel is .sequential : .parallel相反的是.sequential

public static void main(String[] args) {
    IntStream.range(1, 1000).parallel().map(i -> myExpensiveMap(i))
            .sequential()
            .forEach(i -> myCheapOperation(i));
    System.out.println("Expensive Threads:" + expensiveThreads);
    System.out.println("Cheap Threads:    " + cheapThreads);
}

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

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