今日分享开始啦,请大家多多指教~
我问你,你用多线程是为了啥,不就是为了提高一下性能嘛,难不成是为了玩?
多线程就类似N个工人『同一时间』去干同一件事情,比一个人『同一时间』去干快N倍。
但是吧,如果你使用的不合理的话,可能就要被拉去祭天了,哈哈。
下面我给大家列举一下可能会造成多线程性能问题的点:
- 死锁
- 过多串行化
- 过多锁竞争
- 切换上下文
- 内存同步
然后分别解析一下,以上的性能隐患。
一、死锁:
关于死锁,我们在学习操作系统的时候就知道它产生的原因和危害,这里就不从原理上去累述了,可以从下面的代码和图示重温一下死锁产生的原因:
预防和处理死锁的方法:
- 尽量不要在释放锁之前竞争其他锁
- 顺序索取锁资源
- 尝试定时锁
- 检查死锁
二、过多串行化
用多线程实际上就是想并行地做事情,但这些事情由于某些依赖性必须串行工作,导致很多环节得串行化,这实际上很局限系统的可扩展性,就算加CPU加线程,但性能却没有线性增长。
有个Amdahl定理可以说明这个问题:
其中,F是串行化比例,N是处理器数量,由上可知,只有尽可能减少串行化,才能最大化地提高可扩展能力。
降低串行化的关键就是降低锁竞争,当很多并行任务挂在锁的获取上,就是串行化的表现。
三、过多锁竞争
过多锁竞争的危害是不言而喻的,那么看看有哪些办法来降低锁竞争:
- 缩小锁的范围
- 减小锁的粒度
- 减少共享资源的依赖
- 使用读写分离锁来替换独占锁
四、切换上下文
线程比较多的时候,操作系统切换线程上下文的性能消耗是不能忽略的,在构建高性能web之路------web服务器长连接可以看出在进程切换上的代价,当然线程会更轻量一些,不过道理是类似的。
五、内存同步
当使用到synchronized、volatile或Lock的时候,都会为了保证可见性导致更多的内存同步,这就无法享受到JMM结构带来了性能优化。
怎么样,你觉得晕吗?不管怎样,只要你是从事这个行业,那你肯定要必备这个技能。
今日份分享已结束,请大家多多包涵和指点!