parallelStream使用不当引发的血案

Stream简洁

众所周知,java8的新特性中出了lambda表达式之外最受人关注的还有stream一系列的api。
parallelStreamstream中的一个很受开发者喜欢的api,喜欢的同时,如果你使用不当也会造成一些在你看来莫名其妙的问题。
下面我就跟大家说一下在我是如何使用不当遇到那个让我感到奇怪的问题

问题场景描述

  1. 我们的系统中使用了一个会话管理器的东西,就是利用ThreadLocal来制造了一个线程变量,存放每次请求的会话线程的线程变量。
  2. 有一个程序变量需要遍历取值,并且需要对其中的值和线程变量的值来做业务判断,进行处理.
  3. 之前使用Stream进行流操作,未发生任何异常.

问题发生情况描述

  1. 想使用parallelStream提升遍历性能,就将stream改成了parallelStream.
  2. 这时候重启调试之后,请求这个api,总是发生空指针的异常.

问题定位

  1. 因为使用了lambda表达式,所以控制台只是提示parallelStream的遍历这一行报错(这也是使用lambda的不便之处,调错没有之前方便)
  2. 使用debug一步步跟随调试,发现错误定位在了会话管理器获取线程变量这一行

问题思考

  1. 之前在使用stream这个API的时候没有发生问题,便思考到了是parallelStream的原因使得程序产生了问题.
  2. 那么parallelStream怎么会影响我们的会话管理器取得线程变量呢.

问题解决

  1. 查看parallelStream的源码
    parallelStream源码
    .
  2. parallelStream是创建一个并行的Stream,而且他的并行操作是不具备线程传播性的,所以在使用会话管理器的时候是无法获取值的.

问题总结

parallelStream是一把双刃利器,他的并行操作可以在很多时候作为提升效率的一把利刃。但是使用的时候仍需要注意一些东西,以免伤到自己。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,948评论 18 139
  • Java8 in action 没有共享的可变数据,将方法和函数即代码传递给其他方法的能力就是我们平常所说的函数式...
    铁牛很铁阅读 1,274评论 1 2
  • 第一章 为什么要关心Java 8 使用Stream库来选择最佳低级执行机制可以避免使用Synchronized(同...
    谢随安阅读 1,518评论 0 4
  • 尔本世外闲散人,奈何繁杂尘事中,他日化作尘埃去,徒留无趣笑余生
    无趣笑余生阅读 149评论 0 0
  • -1- 那个难得晚起的早晨,睡意朦胧间父亲执着手机轻轻推门进来,“你妈刚打来电话……你外婆去世了……”我从睡梦中一...
    一叶浮生gr阅读 696评论 3 5