国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

ParallelStream的坑,不踩不知道,一踩嚇一跳

安全 應用安全
很多同學喜歡使用lambda表達式,它允許你定義短小精悍的函數,體現你高超的編碼水平。當然,這個功能在某些以代碼行數來衡量工作量的公司來說,就比較吃虧一些。

[[342087]]

本文轉載自微信公眾號「小姐姐味道」,作者小姐姐養的狗  。轉載本文請聯系小姐姐味道公眾號。 

很多同學喜歡使用lambda表達式,它允許你定義短小精悍的函數,體現你高超的編碼水平。當然,這個功能在某些以代碼行數來衡量工作量的公司來說,就比較吃虧一些。

比如下面的代碼片段,讓人閱讀的時候就像是讀詩一樣。但是一旦用不好,也是會要命的。

  1. List<Integer> transactionsIds = 
  2. widgets.stream() 
  3.              .filter(b -> b.getColor() == RED) 
  4.              .sorted((x,y) -> x.getWeight() - y.getWeight()) 
  5.              .mapToInt(Widget::getWeight) 
  6.              .sum(); 

這段代碼有一個關鍵的函數,那就是stream。通過它,可以將一個普通的list,轉化為流,然后就可以使用類似于管道的方式對list進行操作。總之,用過的都說好。

對這些函數還不是太熟悉?可以參考:《到處是map、flatMap,啥意思?》

問題來了

假如我們把stream換成parallelStream,會發生什么情況?

根據字面上的意思,流會從串行 變成并行。

既然是并行,那用屁股想一想,就知道這里面肯定會有線程安全問題。不過我們這里討論的并不是要你使用線程安全的集合,這個話題太低級。現階段,知道在線程不安全的環境中使用線程安全的集合,已經是一個基本的技能。

這次踩坑的地方,是并行流的性能問題。

我們用代碼來說話。

下面的代碼,開啟了8個線程,這8個線程都在使用并行流進行數據計算。在執行的邏輯中,我們讓每個任務都sleep 1秒鐘,這樣就能夠模擬一些I/O請求的耗時等待。

使用stream,程序會在30秒后返回,但我們期望程序能夠在1秒多返回,因為它是并行流,得對得起這個稱號。

測試發現,我們等了好久,任務才執行完畢。

  1. static void paralleTest() { 
  2.     List<Integer> numbers = Arrays.asList( 
  3.             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
  4.             10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
  5.             20, 21, 22, 23, 24, 25, 26, 27, 28, 29 
  6.     ); 
  7.     final long begin = System.currentTimeMillis(); 
  8.     numbers.parallelStream().map(k -> { 
  9.         try { 
  10.             Thread.sleep(1000); 
  11.             System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread()); 
  12.         } catch (InterruptedException e) { 
  13.             e.printStackTrace(); 
  14.         } 
  15.         return k; 
  16.     }).collect(Collectors.toList()); 
  17.  
  18. public static void main(String[] args) { 
  19. //    System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism""20"); 
  20.     new Thread(() -> paralleTest()).start(); 
  21.     new Thread(() -> paralleTest()).start(); 
  22.     new Thread(() -> paralleTest()).start(); 
  23.     new Thread(() -> paralleTest()).start(); 
  24.     new Thread(() -> paralleTest()).start(); 
  25.     new Thread(() -> paralleTest()).start(); 
  26.     new Thread(() -> paralleTest()).start(); 
  27.     new Thread(() -> paralleTest()).start(); 

實際上,在不同的機器上執行,這段代碼花費的時間都不一樣。

既然是并行,那肯定得有個并行度。太低了,體現不到并行的能能力;太大了,又浪費了上下文切換的時間。我是很沮喪的發現,很多高級研發,將線程池的各種參數背的滾瓜爛熟,各種調優,竟然敢睜一只眼閉一只眼的在I/O密集型業務中用上parallelStream。

要了解這個并行度,我們需要查看具體的構造方法。在ForkJoinPool類中找到這樣的代碼。

  1. try {  // ignore exceptions in accessing/parsing properties 
  2.     String pp = System.getProperty 
  3.         ("java.util.concurrent.ForkJoinPool.common.parallelism"); 
  4.     if (pp != null
  5.         parallelism = Integer.parseInt(pp); 
  6.     fac = (ForkJoinWorkerThreadFactory) newInstanceFromSystemProperty( 
  7.         "java.util.concurrent.ForkJoinPool.common.threadFactory"); 
  8.     handler = (UncaughtExceptionHandler) newInstanceFromSystemProperty( 
  9.         "java.util.concurrent.ForkJoinPool.common.exceptionHandler"); 
  10. } catch (Exception ignore) { 
  11.  
  12. if (fac == null) { 
  13.     if (System.getSecurityManager() == null
  14.         fac = defaultForkJoinWorkerThreadFactory; 
  15.     else // use security-managed default 
  16.         fac = new InnocuousForkJoinWorkerThreadFactory(); 
  17. if (parallelism < 0 && // default 1 less than #cores 
  18.     (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0) 
  19.     parallelism = 1; 
  20. if (parallelism > MAX_CAP) 
  21.     parallelism = MAX_CAP; 

可以看到,并行度到底是多少,是由下面的參數來控制的。如果無法獲取這個參數,則默認使用 CPU個數-1 的并行度。

可以看到,這個函數是為了計算密集型業務去設計的。如果你喂給它一大堆任務,它就會由并行執行退變成類似于串行的效果。

  1. -Djava.util.concurrent.ForkJoinPool.common.parallelism=N 

即使你使用-Djava.util.concurrent.ForkJoinPool.common.parallelism=N設置了一個初始值大小,它依然有問題。

因為,parallelism這個變量是final的,一旦設定,不允許修改。也就是說,上面的參數只會生效一次。

張三可能使用下面的代碼,設置了并行度大小為20。

  1. System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism""20"); 

李四可能用同樣的方式,設置了這個值為30。那實際在項目中用的是哪個值,那就得問JVM是怎么加載的類信息了。

這種方式并不太非常靠譜。

一種解決方式

我們可以通過提供外置的forkjoinpool,也就是改變提交方式,來實現不同類型的任務分離。

代碼如下所示,通過顯式的代碼提交,即可實現任務分離。

  1. ForkJoinPool pool = new ForkJoinPool(30); 
  2.  
  3. final long begin = System.currentTimeMillis(); 
  4. try { 
  5.     pool.submit(() -> 
  6.             numbers.parallelStream().map(k -> { 
  7.                 try { 
  8.                     Thread.sleep(1000); 
  9.                     System.out.println((System.currentTimeMillis() - begin) + "ms => " + k + " \t" + Thread.currentThread()); 
  10.                 } catch (InterruptedException e) { 
  11.                     e.printStackTrace(); 
  12.                 } 
  13.                 return k; 
  14.             }).collect(Collectors.toList())).get(); 
  15. } catch (InterruptedException e) { 
  16.     e.printStackTrace(); 
  17. } catch (ExecutionException e) { 
  18.     e.printStackTrace(); 

這樣,不同的場景,就可以擁有不同的并行度。這種方式和CountDownLatch有異曲同工之妙,我們需要手動管理資源。

使用了這種方式,代碼量增加,已經和優雅關系不大了,不僅不優雅,而且丑的要命。白天鵝變成了丑小鴨,你還會愛它么?

 

作者簡介:小姐姐味道 (xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎架構和Linux。十年架構,日百億流量,與你探討高并發世界,給你不一樣的味道。我的個人微信xjjdog0,歡迎添加好友,進一步交流。

 

責任編輯:武曉燕 來源: 小姐姐味道
相關推薦

2025-12-02 07:56:44

SpringBootRedisQPS

2018-05-07 15:44:44

工資騰訊阿里

2023-02-15 17:32:15

2009-06-01 08:45:25

iPhone蘋果移動OS

2022-01-07 11:48:59

RabbitMQGolang 項目

2019-04-18 14:06:35

MySQL分庫分表數據庫

2015-05-22 14:06:16

百度百度搜索這些詞

2009-08-21 10:56:00

2018-03-07 15:19:07

2024-04-01 08:05:27

Go開發Java

2020-09-15 08:46:26

Kubernetes探針服務端

2023-02-20 08:11:04

2025-11-27 02:00:15

2021-07-28 05:01:29

Lombok前端測試

2023-01-18 23:20:25

編程開發

2024-01-09 07:39:20

maven特性版本

2022-07-15 13:09:33

Three.js前端

2024-02-22 08:37:28

NodejsJavaScript運行

2018-01-18 11:59:59

數據庫MySQL

2017-07-17 15:46:20

Oracle并行機制
點贊
收藏

51CTO技術棧公眾號

欧美黄色小说| 国产尤物一区二区在线| 成年网站在线视频网站| 国产综合网站| 91久久香蕉国产日韩欧美9色| 国产精品com| 精品久久久久久亚洲国产300| 羞羞色国产精品| 欧美一级特黄a| 日韩欧美一级| 99久久久精品| 日韩女优av电影在线观看| 久久综合九色欧美狠狠| 麻豆网站在线免费观看| 鲁大师成人一区二区三区| 日韩欧美在线123| 国内精品卡一卡二卡三新区| 婷婷精品进入| 日韩一级黄色大片| 一区二区三区四区视频在线| 欧美电影h版| 99精品欧美一区| 小说区视频区图片区| 亚洲日本在线观看视频| 国产女人aaa级久久久级| 日本国产精品视频| 蜜桃特黄a∨片免费观看| 97精品国产福利一区二区三区| 日本久久电影网| 香蕉av一区| 免费日本视频一区| 色偷偷噜噜噜亚洲男人| 亚洲精品自拍网| 99精品美女| 国产精品视频地址| 超级白嫩亚洲国产第一| 97久久超碰国产精品电影| www.欧美黄色| 亚洲精品进入| 欧美一区三区四区| 黄色三级视频在线| 亚洲视频1区| 久久久精品免费视频| 成人在线观看视频app| 99在线精品视频在线观看| 有码中文亚洲精品| h色视频在线观看| 色哟哟国产精品| 日本人体一区二区| 欧美在线黄色| 日韩亚洲精品视频| 快播av资源| 蜜桃传媒麻豆第一区在线观看| 免费久久久久久| 波多野结衣中文一区| 亚洲一区二区少妇| 国精品产品一区| 一本到不卡精品视频在线观看 | 欧美综合一区二区三区| wwwwww欧美| 中文字幕精品一区二区三区精品| 青青成人在线| 伊甸园亚洲一区| 亚洲最大的网站| 国产精品xnxxcom| 制服.丝袜.亚洲.另类.中文 | 色偷偷亚洲第一成人综合网址 | 伊人75在线| 国产日韩欧美精品一区| 欧美日韩在线观看一区二区三区 | 四虎一区二区| 欧美jjzz| 日本大胆人体视频| 亚洲少妇诱惑| 日韩欧美国产免费| 青青草国产成人99久久| 91老司机在线| 91国内精品| 中文字幕亚洲无线码a| 91小视频xxxx网站在线| 欧美三级免费观看| 日韩欧美亚洲| 国产欧美一区二区三区网站| 免费在线观看一级毛片| 日韩精品视频观看| 色婷婷在线播放| 在线看一区二区| 欧美日韩五区| 亚洲xxxx做受欧美| 91一区二区在线| 欧美激情免费| 欧美亚洲另类视频| 亚洲综合伊人| 亚洲图片在线综合| 日韩成人影视| 欧美亚洲丝袜传媒另类| 男女性激情视频在线观看| 精品日韩欧美一区二区| 午夜视频成人| 91精品国产91久久久久久久久| 天天综合91| 日韩在线视频国产| 国产一区二区三区四区老人| 男人女人黄一级| 国产69精品久久久久777| 艳母动漫在线观看| 韩国一区二区视频| www国产免费| 99久久综合狠狠综合久久| 国产二区在线播放| 色婷婷久久久综合中文字幕| 91麻豆精品激情在线观看最新| 中文字幕亚洲国产| 国产精品资源| 肉丝一区二区| 91精品国产91久久久久久一区二区| 台湾佬综合网| 成人黄色av网| 成人在线国产| 亚洲一区二区三区久久 | 久久影视中文粉嫩av| 亚洲成人自拍网| 中文字幕在线第一页| 欧美午夜视频一区二区| 中文字幕伦av一区二区邻居| 精品免费国产一区二区| 亚洲国产精品成人综合色在线婷婷| 2021天堂中文幕一二区在线观| 日韩成人在线网站| 欧美亚洲网站| 欧美aaa在线观看| 欧美精品第一页| 51漫画成人app入口| 精品国产乱码久久久久久88av| 日韩和欧美的一区| av电影一区二区三区| 日韩欧美亚洲一区二区| 亚洲精品四区| 国产av不卡一区二区| 精品三级av在线| 日韩av一区二| 成人黄色动漫| 最新欧美日韩亚洲| 日韩精品黄色网| 国产99久久久国产精品免费看| 香蕉视频亚洲一级| 久久久久久免费看| 久久99亚洲精品| 成人一区二区| 最新在线地址| 91精品国产99久久久久久红楼| 一本大道综合伊人精品热热| 亚洲精品视频啊美女在线直播| 日本三级在线视频| 亚洲午夜久久久影院伊人| 国产日韩高清在线| 视频精品国内| 国产美女视频黄a视频免费| 欧美人成免费网站| yy6080久久伦理一区二区| 97视频在线播放| 一区二区在线观看视频在线观看| 秋霞成人影院| 亚洲精品tv久久久久久久久| 国产精品免费久久久久| 1pondo在线播放免费| 欧美乱大交xxxxx| 中文字幕日韩一区| 成人国产免费电影| 欧美成人免费一级人片100| 国产主播精品| 青春草在线免费视频| 午夜精品久久久久久99热软件| 国产精品久久久99| 在线视频中文字幕第一页| 国产免费色视频| 97在线视频国产| 91国模大尺度私拍在线视频| 蜜桃视频在线一区| 视频二区欧美毛片免费观看| 激情小视频在线| 欧美激情视频在线免费观看 欧美视频免费一| 羞羞色午夜精品一区二区三区| 女人喷潮完整视频| 欧美人牲a欧美精品| 国产精品一区免费视频| 中文字幕97| 亚洲 国产 日韩 综合一区| 久久亚洲成人精品| 久久99精品久久只有精品| 最近中文视频在线| 欧美一区免费视频| 欧美国产日本高清在线| 久久精品99国产精品| 中文在线二区| 色婷婷精品国产一区二区三区| 最好看的2019的中文字幕视频| 亚洲成av人影院| 国产一区二区三区四区五区传媒| 丰满少妇大力进入|