🍞文章有不合理的地方请各位大佬指正。
🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️
一、parallelStream是什么
简单来说—基于 Java Stream API 的一个并行处理流
//前n个自然数求和
static Long parallelSum(long n) {
return Stream.iterate(1L, i -> i + 1)
.limit(n)
.parallel()
.reduce(0L, (x, y) -> x + y);
}
@Test
void test() {
//1-100累计求和5050
log.info("1-100累计求和{}", parallelSum(100));
}
- 并行流内部使用了默认的
ForkJoinPool, 它默认的 线程数量就是你的处理器数量 - 可通过java代码执行
Runtime.getRuntime().availableProcessors();查看本电脑处理器个数
二、stream、parallelStream、CompletableFuture执行效率执行效率
场景:商品集合如下,取出商品集合所有商品的价格,
//商品类
@Data
@AllArgsConstructor
public static class Shop {
private String name;
private Integer price;
//睡眠1秒 模拟操作过程
private Integer getPrice() {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return price;
}
}
private final List<Shop> shops = Arrays.asList(
new Shop("BestPrice", 1),
new Shop("LetsSaveBig", 2),
new Shop("MyFavoriteShop", 3),
new Shop("BuyItAll", 4));
1.stream
集合中的元素顺序执行
@Test
public void test() {
long start = System.nanoTime();
handleMap();
long time = (System.nanoTime() - start) / 1_000_000;
log.info("执行时长:【{}】ms", time);//4044ms
}
public List<Integer> handleMap() {
return shops.stream()
.map(shop -> shop.getPrice())
.collect(Collectors.toList());
}
2.parallelStream
@Test
public void test() {
long start = System.nanoTime();
handleMap();
long time = (System.nanoTime() - start) / 1_000_000;
log.info("执行时长:【{}】ms", time);//1013ms
}
public List<Integer> handleMap() {
return shops.parallelStream()
.map(shop -> shop.getPrice())
.collect(Collectors.toList());
}
- 根据前文所说
parallelStream最大并行数为处理器个数,当前环境8个处理器 - 当集合中有9个元素时,任务数大于我当前最大处理器数量,
执行时间大约 2018ms
3.CompletableFuture
异步非阻塞执行,默认使用公共线程池ForkJoinPool,线程池数量也等于处理器个数
@Test
public void test1() {
long start = System.nanoTime();
handleMap();
long time = (System.nanoTime() - start) / 1_000_000;
log.info("执行时长:【{}】ms", time);//1014ms
}
public List<Integer> handlMap() {
List<CompletableFuture<Integer>> collect = shops.stream()
.map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice()))
.collect(Collectors.toList());
return collect.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
}
4.如何选择CompletableFuture、parallelStream
- 如果是
计算密集型操作,没有I/O,推荐使用parallelStream,实现简单效率也高 - 操作流程复杂,涉及等待I/O操作,使用
CompletableFuture灵活性更好。CompletableFuture可以实现线程之间顺序依赖、结果依赖。
参考:《java8 实战》
🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️