CAS和hotspot源码
一、用AtomicInteger.addAndGet(int delta)为分析的切入点
/*** Atomically adds the given value to the current value.* 原子化的为当前变量添加一个增量delta 德尔塔为增量,比如原子性的添加1 * @param delta the value to add 需要增加的增量,比如1* @return the updated value 返回的是增加之后的量,比如原来为12 增加1后返回为13*/// setup to use Unsafe.compareAndSwapInt for updates// 所有的原子操作会使用的哦Unsafe这个类,在包:sun.misc下面private static final Unsafe unsafe = Unsafe.getUnsafe();public final int addAndGet(int delta) {return unsafe.getAndAddInt(this, valueOffset, delta) + delta;}
调用Unsafe.java中方法:
/**
* this = var1指当前的类Unsafe
* valueOffset = var2 内存偏移量,为了去oldvalue值
* delta = var4 值增量,比如+1 中的1
/*
public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;}
this.getIntVolatile(var1, var2) 和this.compareAndSwapInt(var1, var2, var5, var5 + var4) 均为native方法,需要看hotspot的源码才行。
二、this.getIntVolatile(var1, var2)
从偏移量中先取出获取当前值
public native int getIntVolatile(Object var1, long var2);
这里先解释下volatile的作用: 参见https://blog.csdn.net/tigerjibo/article/details/7427366
三、this.compareAndSwapInt(var1, var2, var5, var5 + var4)
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
调用unsafe.cpp的
{CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)},
调用Unsafe_CompareAndSwapInt方法:
/**
src/share/vm/prims/unsafe.cppoffset : value偏移
e:getIntVolatile读到的最新值,也即期望值
x:要更新的值即v + delta的值
*/
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))UnsafeWrapper("Unsafe_CompareAndSwapInt");oop p = JNIHandles::resolve(obj);jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
调用Atomic::cmpxchg:
/**
src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp
比较dest处的值与compare_value值是否相等,相等则说明未被更改,则将新值exchange_value更新到dest,返回exchange_value
*/
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {int mp = os::is_MP();//asm : assembly汇编// LOCK_IF_MP如果是多核则加锁MP(multi processor)// 硬件支持,完成cas__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)": "=a" (exchange_value): "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp): "cc", "memory");return exchange_value;
}
src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp
判断处理器数量 > 0 时,执行lock指令,锁定总线,刷新数据到内存,使各处理器的缓存失效,保证目标值对其他线程立即可见+
#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
Intel手册对lock前缀指令保证:确保对内存的读改写操作原子执行
禁止该指令与之前和之后的读或写指令重排序
把写缓冲区中的所有数据刷新到内存中
这三条足以同时满足volatile读和写内存的语义,所以说CAS同时满足了volatile的读写语义,这个语义作为CAS的充分条件,使得CAS原子操作在不加锁时能够保证变量的读写对其他线程立即可见。可以看到在多处理器系统上AtomicInteger的整个自增操作可能伴随着多次lock操作。do {} while() 循环可能非常耗时。CAS即是天使也是魔鬼
————————————————参考原文:https://blog.csdn.net/u013928208/article/details/109317172
https://blog.csdn.net/killerofjava/article/details/114173767
CAS和hotspot源码相关推荐
- 深入Hotspot源码,搞清楚JVM的本质
记得我在早些年研究JVM底层的时候,每次遇到native就束手无策,导致每次的底层研究之旅"无疾而终".后来赌气逼着自己学了汇编.C语言.C++--才逐渐让自己对JVM的认知由纯理 ...
- hotspot源码角度看OOP之类属性的底层实现(一)
hello,大家好,我是江湖人送外号[道格牙]的子牙老师. 最近看hotspo源码有点入迷.hotspot就像一座宝库,等你探索的东西太多了.每次达到一个新的Level回头细看,都有不同的感触.入迷归 ...
- Hotspot源码解析一
文章目录 call_stub _call_stub_entry例程 JAVA数据结构与面向对象 解析魔数 java字节码 试了一天,windows一直失败.无奈了.安装了一个linux明天试试. 詹姆 ...
- 双管齐下,JDK源码+HotSpot源码一次性学完
JDK源码手册 除了第一章节的内容外,我们会从第二章开始自下而上,从简单到复杂的有顺序的深度学习整个Concurrent包! Semaphore(Semaphore也就是信号量,提供了资源数量的并 ...
- hotspot源码下载
jdk的开源主要体现openjdk项目上,下面简单介绍一下jdk及其子项目hotspot的源码下载方式. 查看全文 http://www.taodudu.cc/news/show-3524756.ht ...
- 如何下载hotspot源码
怎么下载jvm的源码,当然下载的是openjdk的jvm源码: 1. http://hg.openjdk.java.net/ 选择格式下载即可: 各路径的意义: ├─agent ...
- 下载hotspot源码
这里穿插,怎么下载jvm的源码,当然下载的是openjdk的jvm源码: 1. http://hg.openjdk.java.net/ 选择格式下载即可: 各路径的意义: ├─agent Servic ...
- Java并发基础:了解无锁CAS就从源码分析
CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...
- Java并发基础:了解无锁CAS就从源码分析 1
CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...
最新文章
- java jnotify_java JNotify (基于内核)实时监控文件
- python小程序-【Python精华】100个Python练手小程序
- jenkins调整jdk版本不生效的解决办法
- 【Python基础】字符串专题总结
- HDU1226 搜索 bfs xingxing在努力
- mysql 5.7 my.cnf 为空_mysql 5.7 的 /etc/my.cnf
- Http状态码完整说明
- Silverlight MMORPG网页游戏开发课程(Game Lesson):目录
- python定义只有一个元素的元组
- 小菜面试 String 篇 之 统计一个字符串中数字,字母,的个数
- D11:Chickens and Rabbits(鸡兔同笼问题,附题解)
- 中山大学计算机软件专业,【广州日报】中山大学在珠海校区新成立人工智能学院和软件工程学院...
- 概率计算机在线,高斯正态分布(概率)计算公式与在线计算器_三贝计算网_23bei.com...
- Java实现扑克牌游戏(简易炸金花)
- 《金融科技(FinTech)发展规划(2019-2021年)》梳理
- SEO网站优化步骤和技巧小结
- 5、TM4的PD7和PF0解锁问题
- Halcon 第七章『图像的几何变换』◆第1节:图像的仿射变换(位置变换、形状变换)及应用
- 计算机中软件和硬件的简单介绍
- python中使用linux命令