如何在Java-8中并行运行某些中间操作?

时间:2018-01-07 17:23:39

标签: java multithreading java-8

我试图模仿WireTapSpring Integration的行为。 java8 stream中的Apache Camel,其中将当前处理数据的副本传递给WireTap以便在单独的线程中对其进行处理,这对于记录&审计

这里我只希望登录peek想要在单独的线程上运行

List<String> lines = ...

List<String> upperLines = lines.stream()
    .map(String::toUpperCase)
    .parallel() // which is hidden by the sequential
    .peek(line -> System.out.println(line)) // don't want to run this fully on main thread
    .sequential()
    .collect(Collectors.toList());

我是否需要使用BlockingQueueExecutorService实施单独的方法来执行此操作

.peek(this::logger)

1 个答案:

答案 0 :(得分:2)

没有办法以不同的模式处理流管道的各个部分,并且实现这种混合模式管道也没有好处,给定,提交异步作业的简单方法就在你身边:

ExecutorService es = Executors.newFixedThreadPool(4);
List<String> upperLines = lines.stream()
    .map(String::toUpperCase)
    .peek(line -> es.execute(() -> System.out.println(line)))
    .collect(Collectors.toList());
es.shutdown();

List<String> upperLines = lines.stream()
    .map(String::toUpperCase)
    .peek(line -> CompletableFuture.runAsync(() -> System.out.println(line)))
    .collect(Collectors.toList());
// when running this in the main method, avoid JVM termination before the async jobs:
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.DAYS);

但请注意,在这种特定情况下,实际上没有可感知的差别,例如

List<String> upperLines = lines.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
upperLines.parallelStream().forEach(line -> System.out.println(line));

或者,如果您不想等待完成日志记录语句:

List<String> upperLines = lines.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
upperLines.forEach(line -> CompletableFuture.runAsync(() -> System.out.println(line)));