volatile底层实现原理

定义

java编程语言允许线程访问共享变量,为了确保共享变量能够被准确和一致的更新,线程应该通过排他锁获得这个变量。java提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到的这个变量的值是一致的。

汇编代码

使用命令获得汇编代码

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
Loaded disassembler from /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/hsdis-amd64.dylib
Decoding compiled method 0x0000000110da4b50:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Constants]
  # {method} {0x000000010f163000} 'hashCode' '()I' in 'java/lang/String'
  #           [sp+0x40]  (sp of caller)
  0x0000000110da4cc0: mov    0x8(%rsi),%r10d
  0x0000000110da4cc4: shl    $0x3,%r10
  0x0000000110da4cc8: cmp    %rax,%r10
  0x0000000110da4ccb: jne    0x0000000110ceae20  ;   {runtime_call}
  0x0000000110da4cd1: data32 data32 nopw 0x0(%rax,%rax,1)
  0x0000000110da4cdc: data32 data32 xchg %ax,%ax
[Verified Entry Point]
  0x0000000110da4ce0: mov    %eax,-0x14000(%rsp)
  0x0000000110da4ce7: push   %rbp
  0x0000000110da4ce8: sub    $0x30,%rsp
  ......

mac系统下使用此命令的前提是下载hsdis-amd64.dylib,并将其放入到jdk的jre下的lib目录下

实现原理

通过利用工具获得class文件的汇编代码,会发现,标有volatile的变量在进行写操作时,会在前面加上lock质量前缀。

这里写图片描述

而lock指令前缀会做如下两件事

  1. 将当前处理器缓存行的数据写回到内存。lock指令前缀在执行指令的期间,会产生一个lock信号,lock信号会保证在该信号期间会独占任何共享内存。lock信号一般不锁总线,而是锁缓存。因为锁总线的开销会很大。

  2. 将缓存行的数据写回到内存的操作会使得其他CPU缓存了该地址的数据无效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值