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