日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
只要使用這個(gè)功能,程序運(yùn)行速度瞬間提升,高到離譜!

本文轉(zhuǎn)載自微信公眾號「小明菜市場」,作者小明菜市場 。轉(zhuǎn)載本文請聯(lián)系小明菜市場公眾號。

云安網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)2013年至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

 前言

在之前如果需要處理集合需要先手動分成幾部分,然后為每部分創(chuàng)建線程,最后在合適的時(shí)候合并,這是手動處理并行集合的方法,在java8中,有了新功能,可以一下開啟并行模式。

并行流

認(rèn)識開啟并行流

并行流是什么?是把一個(gè)流內(nèi)容分成多個(gè)數(shù)據(jù)塊,并用不同線程分別處理每個(gè)不同數(shù)據(jù)塊的流。例如,有下面一個(gè)例子,在List中,需要對List數(shù)據(jù)進(jìn)行分別計(jì)算,其代碼如下所示:

 
 
 
  1. List appleList = new ArrayList<>(); // 假裝數(shù)據(jù)是從庫里查出來的
  2. for (Apple apple : appleList) {
  3.     apple.setPrice(5.0 * apple.getWeight() / 1000);
  4. }

在這里,時(shí)間復(fù)雜度為O(list.size),隨著list的增加,耗時(shí)也在增加。并行流可以解決這個(gè)問題,代碼如下所示:

appleList.parallelStream().forEach(apple -> apple.setPrice(5.0 * apple.getWeight() / 1000));

這里通過調(diào)parallelStream()說明當(dāng)前流為并行流,然后進(jìn)行并行執(zhí)行。并行流內(nèi)部使用了默認(rèn)的ForkJoinPool線程池,默認(rèn)線程數(shù)為處理器的核心數(shù)。

測試并行流

普通代碼如下所示:

 
 
 
  1. public static void main(String[] args) throws InterruptedException {
  2.     List appleList = initAppleList();
  3.     Date begin = new Date();
  4.     for (Apple apple : appleList) {
  5.         apple.setPrice(5.0 * apple.getWeight() / 1000);
  6.         Thread.sleep(1000);
  7.     }
  8.     Date end = new Date();
  9.     log.info("蘋果數(shù)量:{}個(gè), 耗時(shí):{}s", appleList.size(), (end.getTime() - begin.getTime()) /1000);
  10. }

輸出的內(nèi)容為耗時(shí)4s。

并行代碼如下所示:

 
 
 
  1. List appleList = initAppleList();
  2. Date begin = new Date();
  3. appleList.parallelStream().forEach(apple ->
  4.                                    {
  5.                                        apple.setPrice(5.0 * apple.getWeight() / 1000);
  6.                                        try {
  7.                                            Thread.sleep(1000);
  8.                                        } catch (InterruptedException e) {
  9.                                            e.printStackTrace();
  10.                                        }
  11.                                    }
  12.                                   );
  13. Date end = new Date();
  14. log.info("蘋果數(shù)量:{}個(gè), 耗時(shí):{}s", appleList.size(), (end.getTime() - begin.getTime()) /1000);

輸出結(jié)果為耗時(shí)1s。可以看到耗時(shí)大大提升了3s。

并行流拆分會影響流的速度

對于并行流來說需要注意以下幾點(diǎn):

對于 iterate 方法來處理的前 n 個(gè)數(shù)字來說,不管并行與否,它總是慢于循環(huán)的,

而對于 LongStream.rangeClosed() 方法來說,就不存在 iterate 的第兩個(gè)痛點(diǎn)了。它生成的是基本類型的值,不用拆裝箱操作,另外它可以直接將要生成的數(shù)字 1 - n 拆分成 1 - n/4, 1n/4 - 2n/4, ... 3n/4 - n 這樣四部分。因此并行狀態(tài)下的 rangeClosed() 是快于 for 循環(huán)外部迭代的

代碼如下所示:

 
 
 
  1. package lambdasinaction.chap7;
  2. import java.util.stream.*;
  3. public class ParallelStreams {
  4.     public static long iterativeSum(long n) {
  5.         long result = 0;
  6.         for (long i = 0; i <= n; i++) {
  7.             result += i;
  8.         }
  9.         return result;
  10.     }
  11.     public static long sequentialSum(long n) {
  12.         return Stream.iterate(1L, i -> i + 1).limit(n).reduce(Long::sum).get();
  13.     }
  14.     public static long parallelSum(long n) {
  15.         return Stream.iterate(1L, i -> i + 1).limit(n).parallel().reduce(Long::sum).get();
  16.     }
  17.     public static long rangedSum(long n) {
  18.         return LongStream.rangeClosed(1, n).reduce(Long::sum).getAsLong();
  19.     }
  20.     public static long parallelRangedSum(long n) {
  21.         return LongStream.rangeClosed(1, n).parallel().reduce(Long::sum).getAsLong();
  22.     }
  23. }
  24. package lambdasinaction.chap7;
  25. import java.util.concurrent.*;
  26. import java.util.function.*;
  27. public class ParallelStreamsHarness {
  28.     public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();
  29.     public static void main(String[] args) {
  30.         System.out.println("Iterative Sum done in: " + measurePerf(ParallelStreams::iterativeSum, 10_000_000L) + " msecs");
  31.         System.out.println("Sequential Sum done in: " + measurePerf(ParallelStreams::sequentialSum, 10_000_000L) + " msecs");
  32.         System.out.println("Parallel forkJoinSum done in: " + measurePerf(ParallelStreams::parallelSum, 10_000_000L) + " msecs" );
  33.         System.out.println("Range forkJoinSum done in: " + measurePerf(ParallelStreams::rangedSum, 10_000_000L) + " msecs");
  34.         System.out.println("Parallel range forkJoinSum done in: " + measurePerf(ParallelStreams::parallelRangedSum, 10_000_000L) + " msecs" );
  35.     }
  36.     public static  long measurePerf(Function f, T input) {
  37.         long fastest = Long.MAX_VALUE;
  38.         for (int i = 0; i < 10; i++) {
  39.             long start = System.nanoTime();
  40.             R result = f.apply(input);
  41.             long duration = (System.nanoTime() - start) / 1_000_000;
  42.             System.out.println("Result: " + result);
  43.             if (duration < fastest) fastest = duration;
  44.         }
  45.         return fastest;
  46.     }
  47. }

共享變量會造成數(shù)據(jù)出現(xiàn)問題

 
 
 
  1. public static long sideEffectSum(long n) {
  2.     Accumulator accumulator = new Accumulator();
  3.     LongStream.rangeClosed(1, n).forEach(accumulator::add);
  4.     return accumulator.total;
  5. }
  6. public static long sideEffectParallelSum(long n) {
  7.     Accumulator accumulator = new Accumulator();
  8.     LongStream.rangeClosed(1, n).parallel().forEach(accumulator::add);
  9.     return accumulator.total;
  10. }
  11. public static class Accumulator {
  12.     private long total = 0;
  13.     public void add(long value) {
  14.         total += value;
  15.     }
  16. }

并行流的注意

  1. 盡量使用 LongStream / IntStream / DoubleStream 等原始數(shù)據(jù)流代替 Stream 來處理數(shù)字,以避免頻繁拆裝箱帶來的額外開銷
  2. 要考慮流的操作流水線的總計(jì)算成本,假設(shè) N 是要操作的任務(wù)總數(shù),Q 是每次操作的時(shí)間。N * Q 就是操作的總時(shí)間,Q 值越大就意味著使用并行流帶來收益的可能性越大
  3. 對于較少的數(shù)據(jù)量,不建議使用并行流
  4. 容易拆分成塊的流數(shù)據(jù),建議使用并行流

當(dāng)前題目:只要使用這個(gè)功能,程序運(yùn)行速度瞬間提升,高到離譜!
當(dāng)前路徑:http://www.5511xx.com/article/dphssdi.html