Stream簡潔
眾所周知,java8
的新特性中出了lambda
表達式之外最受人關注的還有stream
一系列的api。
parallelStream
是stream
中的一個很受開發者喜歡的api,喜歡的同時,如果你使用不當也會造成一些在你看來莫名其妙的問題。
下面我就跟大家說一下在我是如何使用不當遇到那個讓我感到奇怪的問題
。
問題場景描述
- 我們的系統中使用了一個會話管理器的東西,就是利用ThreadLocal來制造了一個線程變量,存放每次請求的會話線程的線程變量。
- 有一個程序變量需要遍歷取值,并且需要對其中的值和線程變量的值來做業務判斷,進行處理.
- 之前使用Stream進行流操作,未發生任何異常.
問題發生情況描述
- 想使用
parallelStream
提升遍歷性能,就將stream
改成了parallelStream
. - 這時候重啟調試之后,請求這個api,總是發生空指針的異常.
問題定位
- 因為使用了lambda表達式,所以控制臺只是提示
parallelStream
的遍歷這一行報錯(這也是使用lambda的不便之處,調錯沒有之前方便) - 使用debug一步步跟隨調試,發現錯誤定位在了會話管理器獲取線程變量這一行
問題思考
- 之前在使用
stream
這個API的時候沒有發生問題,便思考到了是parallelStream
的原因使得程序產生了問題. - 那么
parallelStream
怎么會影響我們的會話管理器取得線程變量呢.
問題解決
- 查看
parallelStream
的源碼parallelStream源碼 - parallelStream是創建一個并行的Stream,而且他的并行操作是不具備線程傳播性的,所以在使用會話管理器的時候是無法獲取值的.
問題總結
parallelStream
是一把雙刃利器,他的并行操作可以在很多時候作為提升效率的一把利刃。但是使用的時候仍需要注意一些東西,以免傷到自己。