我试图模仿WireTap
中Spring 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());
我是否需要使用BlockingQueue
或ExecutorService
实施单独的方法来执行此操作
.peek(this::logger)
答案 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)));