多线程带来的性能问题

多线程带来的性能问题:

调度:上下文切换

* 什么是上下文切换

  • 什么是上下文切换:当一个线程调用Thread.sleep()想进入阻塞状态,线程调度器就会阻塞这个线程,然后让另一个等待CPU资源的线程进入的Runnable状态,这个动作就是一个上下文切换。开销很大,有时比线程执行时间都长,通常一次上下文切换会消耗5000-10000个CPU时钟周期,大约是几微秒,对于CPU而言,是一个很大的开销了。

* 什么是上下文

  • 什么是上下文:一次上下文切换,主要包含以下活动,首先要挂起一个线程,然后把这个线程的状态存在内存的某处,这个状态就是上下文。

* 缓存开销

  • 缓存开销:缓存失效。CPU会根据算法会将很多数据缓存到CPU里面以便下次更快的再次使用。但是一旦进行了上下文切换,CPU即将执行不同线程不同代码,原来的缓存就失去了价值,所以CPU就需要重新进行缓存,这导致线程被调度后一开始的速度有点慢,是因为之前的缓存大部分都失效了。所以CPU为了防止这种情况,设置了一个最小开销时间,两次上下文切换之间,不能小于这个最小开销时间,否则因为缓存带来的开销可能大于程序本身的执行时间。

* 何时会导致密集的上下文切换

  • 何时会导致密集的上下文切换:抢锁、IO等导致线程频繁的阻塞,就会导致频繁的上下文切换。

协作

  • 协作: 内存同步
    我们编辑器包括CPU会优化我们的程序,比如说可能会指令重排序,让我们的缓存能利用的更多些;或者JVM会优化我们的锁,发现没必要的锁会进行删除;或者内存方面,由于JMM java内存模型规定我们有主内存以及各个CPU有自己的缓存,这种情况下,使用缓存能提高程序的速度,因为不必要每次对主存进行同步,但是对于多线程,我们经常使用synchronized、volatile关键字去禁止,或让不同线程的缓存会失效,这样的话也会因为内存同步问题带来开销,因为它就没办法在自己的CPU里做进一步的缓存,只能使用主存,降低了效率。

上篇:线程安全第三大类问题——对象发布和初始化的安全问题
下篇:JVM内存结构、Java对象模型、Java内存模型(JMM)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值