文章來源:https://blog.csdn.net/lihua5419/article/details/86678860
先上代碼
public static void main(String[] args){ List<Integer> i=Arrays.asList(1,2,3,4,5,6,7); System.out.println("stream.forEach打印結果如下"); i.stream().forEach(System.out :: println);//固定結果 1234567 System.out.println("parallelStream.forEach打印結果如下"); i.parallelStream().forEach(System.out :: println);//每次的結果都不同 System.out.println("parallelStream.forEachOrdered打印結果如下"); i.parallelStream().forEachOrdered(System.out :: println);//結果同stream.forEach }
通過打印結果發現parallelStream每次執行的結果都不相同,與多線程程序中執行的結果類似。
於是乎便有了以下代碼:
public static void main(String[] args){ //模擬10000條數據 循環打印測試 List<Integer> list = new ArrayList(); for (int j = 0; j < 10000; j++) { list.add(j); } // 統計並行執行list的線程 Set<Thread> threadSet = new CopyOnWriteArraySet<>(); // 並行執行 list.parallelStream().forEach(integer -> { Thread thread = Thread.currentThread(); // 統計並行執行list的線程 threadSet.add(thread); }); System.out.println(threadSet); System.out.println("threadSet一共有" + threadSet.size() + "個線程");//打印結果由此證明parallelStream是多管道線程 System.out.println("系統一個有"+Runtime.getRuntime().availableProcessors()+"個cpu"); }
打印的結果每次都不相同,那么stream和parallelstream執行起來的效率又有什么區別呢?
又於是乎,便有了以下代碼:
public static void main(String[] args) throws InterruptedException { //模擬10000條數據 forEach打印測試 List<Integer> list = new ArrayList(); for (int j = 0; j < 10000; j++) { list.add(j); } //下面測試下各方法執行的時間 檢查效率 long startTime = System.currentTimeMillis(); for (int i = 0; i < list.size(); i++) { try { TimeUnit.MILLISECONDS.sleep(1);//睡眠1毫秒 } catch (InterruptedException e) { e.printStackTrace(); } } long endTime = System.currentTimeMillis(); System.out.println("傳統for循環運行時間:" + (endTime - startTime) + "ms"); // 測試單管道stream執行效率 startTime = System.currentTimeMillis(); list.stream().forEach(r -> { try { TimeUnit.MILLISECONDS.sleep(1);//睡眠1毫秒 } catch (Exception e) { e.printStackTrace(); } }); long streamendTime = System.currentTimeMillis(); System.out.println("stream : " + (streamendTime - startTime) + "ms"); // 測試多管道parallelStream執行效率 startTime = System.currentTimeMillis(); list.parallelStream().forEach(r -> { try { TimeUnit.MILLISECONDS.sleep(1);//睡眠1毫秒 } catch (Exception e) { e.printStackTrace(); } }); long parallelStreamendTime = System.currentTimeMillis(); System.out.println("parallelStream : " + (parallelStreamendTime - startTime) + "ms"); }
傳統for循環運行時間:21058ms
stream : 20315ms
parallelStream : 2441ms
對比發現parallelStream執行效率要比傳統的for循環和stream要快的多,
那么什么時候要用stream或者parallelStream呢?可以從以下三點入手考慮
- 是否需要並行?
- 任務之間是否是獨立的?是否會引起任何競態條件?
- 結果是否取決於任務的調用順序?
