背景
线上发现盘后资产重算cpu飙高,导致扩容
jdk 版本:1.8
openjdk version "1.8.0_332"
问题原因
/** * 使用CompletableFuture + parallelStream * 有问题 */ @Test public void test7() { List<Integer> items = IntStream.range(0, 1000000).boxed().collect(Collectors.toList()); items.parallelStream().forEach(item -> { completableFutureRun(item); }); } /** * 使用CompletableFuture + ForkJoinPool * 有问题 */ @Test public void test8() throws InterruptedException { int count = 100; CountDownLatch countDownLatch = new CountDownLatch(count); for (int i = 0; i < count; i++) { int finalI = i; ForkJoinPool.commonPool().execute(() -> { completableFutureRun(finalI); countDownLatch.countDown(); }); } countDownLatch.await(); } private void completableFutureRun(int finalI) { try { List<CompletableFuture<String>> completableFutures = new ArrayList<>(); IntStream.range(0, 10).forEach(j -> { CompletableFuture<String> mlegPositionList = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { throw new RuntimeException(e); } return Thread.currentThread().getName(); }, asyncLoadService.getExecutorService()); completableFutures.add(mlegPositionList); }); for (CompletableFuture<String> completableFuture : completableFutures) { String result = completableFuture.get(); //log.info("inner item " + item + " by " + result); } } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); } System.out.println("Processing item " + finalI + " by " + Thread.currentThread().getName()); } |
其他场景验证(没有问题)
/** * 没有线程池的多线程 * 没有问题 */ @Test public void test5() { List<Integer> items = IntStream.range(0, 1000000).boxed().collect(Collectors.toList()); items.parallelStream().forEach(item -> { try { CountDownLatch countDownLatch = new CountDownLatch(10); IntStream.range(0, 10).forEach(i -> { new Thread(() -> { try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } countDownLatch.countDown(); }).start(); }); countDownLatch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("Processing item " + item + " by " + Thread.currentThread().getName()); }); } /** * 使用线程池的多线程 没有问题 */ @Test public void test6() { List<Integer> items = IntStream.range(0, 1000000).boxed().collect(Collectors.toList()); items.parallelStream().forEach(item -> { try { CountDownLatch countDownLatch = new CountDownLatch(10); IntStream.range(0, 10).forEach(i -> { asyncLoadService.getExecutorService().execute(new Thread(() -> { try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } countDownLatch.countDown(); })); }); countDownLatch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("Processing item " + item + " by " + Thread.currentThread().getName()); }); } |