java concurrent-AtomicInteger

一、内容:

主要简单说下AtomicInteger的getAndIncrement的实现方式


二、跟随源码到达最深的位置:

java入口:


unsafe-java:


unsafe-native-method(可以看到是native方法,说明是调用本地的c++相关代码方法):


通过下载openjdk1.7,在hotspot/src/share/vm/prims/unsafe.cpp可以找到下面的接口:


最终可以到达hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp:


这段内联汇编代码便是最终的核心代码了

1.cas(比较赋值)是通过x86指令cmpxchgl实现的。

2.该内联代码等价伪汇编代码(因为实际compare_value、exchange_value和desc是不能这么直接写在汇编里的,这里只是个大体意思):

mov compare_value, %eax
mov exchange_value, %edx
mov dest, %rcx
mov is_mutiple_processor, %esi 
cmp $0, %esi; je 1f; lock; 1: cmpxchgl %edx,(%rcx)
1.

寄存器eax存放着compare_value(旧值-即dest内存中所指向位置的值)的值,

寄存器edx存放着exchange_value(要修改的值)的值,

寄存器rcx存放的是dest(要修改内存中的地址值)的值, 

寄存器esi存放是当前系统运行的是否是多核系统

2.cmp $0, %esi; je 1f;

判断当前是否是单核系统,是的话跳到1:处(即会跳过lock指令,不执行)

如果为多核系统,则会继续往下执行,则会执行lock指令

3.lock指令

lock执行跟随的后面的相关指令会变为原子操作,相关地址描述:http://www.felixcloutier.com/x86/LOCK.html

4.cmpxchgl %edx, (%rcx)

这里会读取(%rcx)中所指向内存的值temp,然后判断该值temp和寄存器eax所存放的值(compare_value)是否相等,

如果相等,则会将寄存器中edx的值存入到(%rcx)所指向内存的位置上,额外zf会设置为1

如果不相等,则会将temp值存入到(%rcx)所指向内存的位置上,额外zf会设置为0

所以在多核模式下,一个线程比较的值temp和后面写入时的temp的值可能已经发生改变了,因此需要加lock前缀指令,来保证多核情况下该cmpxchgl指令为原子操作。

lock前缀指令并不是所有指令适用,相关地址描述:http://www.felixcloutier.com/x86/CMPXCHG.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值