并发编程的艺术:第二章

第二章:Java并发机制的底层实现原理

  • Java代码在编译之后会生成字节码文件,也就是.class文件。class文件经过类加载器的加载到JVM中,JVM解释字节码文件,最终转化为汇编指令在CPU上执行。Java中所使用的并发机制依赖于JVM的实现和CPU的指令

2:volatile

  • 保证了所有变量的内存可见性
  • 修改完之后,就会立即写入内存,并且告诉各个CPU中的缓存失效
  • 汇编指令:LOCK
    • 将当前的缓存行写入内存中
    • 锁总线,或者是锁缓存
    • 告诉其他的COU缓存的数据无效

3:synchronized

1:锁的对象
  • 普通的同步方法,锁的是该实例
  • static静态方法,锁的是class对象
  • 同步方法块,锁的是括号中的对象
2:原理
  • JVM基于进入和退出monitor对象来实现方法同步和代码块进行同步。代码块的同步时使用monitorenter和monitorexit指令进行实现的,但是方法的同步不是。
  • monitorenter指令是在编译后插入到同步代码块开始的位置,monitorexit是在方法结尾的地方,当有一个monitor被持有的时候,他就会处于锁定的状态。线程执行到monitor的时候,就会尝试获得对象所持有的锁。
3:Java对象头
  • mark word 对象头
    • hashcod GC年龄 锁(一位是偏向锁,两位锁的标志)
    • 偏向锁:线程ID + Epoch + GC年龄 + 1 + 01
      • Epoch表示重偏向了几次,记录偏向锁被撤销的次数,当次数达到阈值的时候,就不会分配偏向锁。
    • 轻量级锁:指向栈中锁记录的指针 + 00
    • 重量级锁:指向互斥量的指针 + 10
    • GC标记:空 + 11
  • 存储该对象类型数据的指针
4:锁的升级
  • 偏向锁
    • 对象头和锁记录中存放偏向的线程ID
  • 轻量级锁
    • JVM会在当前的线程栈中创建用于存储锁记录的空间,并将对象头中的mark word复制到锁记录中,即displaced mark word。
    • 然后线程进行CAS将对象头中的mark word替换为指向锁记录的指针,如果成功,当前的线程获得锁。
  • 重量级锁
    • 线程堵塞,响应时间缓慢
5:实现原子操作
  • 总线加锁

    • 处理器提供一个LOCK信号,当一个处理器在总线上输出此信号的时候,其他处理器的请求将会被阻塞,该处理器可以独占共享内存
  • 缓存锁

    • 写回的时候,不再发送LOCK信号,而是修改内部的内存地址,并通过缓存一致性的机制来保证操作的原子性。阻止两个以上的CPU同时修改自己的缓存信息
      • 数据不能被缓存在处理器内部的时候,或者是跨多个缓存行的时候,就不能使用缓存锁
      • 有一些处理器不支持缓存锁定
6:Java实现原子操作
  • CAS
    • CAMXCHG
    • 三大问题
      • ABA
      • 循环性能问题
      • 只能改变单个变量
  • 锁机制
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值