今日分享开始啦,请大家多多指教~

我问你,你用多线程是为了啥,不就是为了提高一下性能嘛,难不成是为了玩?

多线程就类似N个工人『同一时间』去干同一件事情,比一个人『同一时间』去干快N倍。

但是吧,如果你使用的不合理的话,可能就要被拉去祭天了,哈哈。

下面我给大家列举一下可能会造成多线程性能问题的点:

  • 死锁
  • 过多串行化
  • 过多锁竞争
  • 切换上下文
  • 内存同步

然后分别解析一下,以上的性能隐患。

一、死锁:

关于死锁,我们在学习操作系统的时候就知道它产生的原因和危害,这里就不从原理上去累述了,可以从下面的代码和图示重温一下死锁产生的原因:

预防和处理死锁的方法:

  1. 尽量不要在释放锁之前竞争其他锁
  2. 顺序索取锁资源
  3. 尝试定时锁
  4. 检查死锁

二、过多串行化

用多线程实际上就是想并行地做事情,但这些事情由于某些依赖性必须串行工作,导致很多环节得串行化,这实际上很局限系统的可扩展性,就算加CPU加线程,但性能却没有线性增长。

有个Amdahl定理可以说明这个问题:

其中,F是串行化比例,N是处理器数量,由上可知,只有尽可能减少串行化,才能最大化地提高可扩展能力。

降低串行化的关键就是降低锁竞争,当很多并行任务挂在锁的获取上,就是串行化的表现。

三、过多锁竞争

过多锁竞争的危害是不言而喻的,那么看看有哪些办法来降低锁竞争:

  1. 缩小锁的范围
  2. 减小锁的粒度
  3. 减少共享资源的依赖
  4. 使用读写分离锁来替换独占锁

四、切换上下文

线程比较多的时候,操作系统切换线程上下文的性能消耗是不能忽略的,在构建高性能web之路------web服务器长连接可以看出在进程切换上的代价,当然线程会更轻量一些,不过道理是类似的。

五、内存同步

当使用到synchronized、volatile或Lock的时候,都会为了保证可见性导致更多的内存同步,这就无法享受到JMM结构带来了性能优化。

怎么样,你觉得晕吗?不管怎样,只要你是从事这个行业,那你肯定要必备这个技能。

今日份分享已结束,请大家多多包涵和指点!