CAS AtomicInteger 源码解析
来源:互联网 发布:qp个案分析比赛知乎 编辑:程序博客网 时间:2024/06/06 07:29
1.CAS简介(复制的,可以跳过看后面代码实例)
CAS,Compare and Swap即比较并替换,设计并发算法时常用到的一种技术,Doug lea大神在java同步器中大量使用了CAS技术,鬼斧神工的实现了多线程执行的安全性。
目前的处理器基本都支持CAS,只不过不同的厂家的实现不一样罢了。CAS有三个操作数:内存值V、旧的预期值A、要修改的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做并返回false。
public class CAS { private static Unsafe unsafe ; static{ loadUnsafe(); } private static void loadUnsafe() { try { /**Unsafe在rt.jar下,不能直接实例化。必须通过反射*/ Field field = Unsafe.class.getDeclaredField("theUnsafe") ; field.setAccessible(true); unsafe = (Unsafe)field.get(null); } catch (Exception e) { e.printStackTrace(); } } static class Data{ int intParam ; } public static void main(String[] args) throws NoSuchFieldException, SecurityException { // objectFieldOffset : 获取 intParam 字段的内存偏移地址 long intParamOffset = unsafe.objectFieldOffset(Data.class.getDeclaredField("intParam")) ; System.out.println(intParamOffset); Data data = new Data(); data.intParam = 2 ; /*** * compareAndSwapInt 比较和 修改值 ,是原子操作 * 参数1: 要修改的对象 * 参数2:对象字段的偏移地址 * 参数3:预期值(如果等于原始值,则修改成功) * 参数4:修改后的值 */ boolean ret = unsafe.compareAndSwapInt(data, intParamOffset, 2, 13);//原值2, 等于预期值2,能改成功 if(ret){ System.out.println("修改intParam成功 , val:"+data.intParam); } ret = unsafe.compareAndSwapInt(data, intParamOffset, 2, 12); if(!ret){ System.out.println("修改失败"); } }}执行结果12修改intParam成功 , val:13修改失败
3.AtomicInteger分析(必须要上面基础)
这里就将了一个getAndSet方法,但是我想就已经足够了。详细解释见 注释。
public class AtomicInteger { // jdk自己可以使用, 所以不用我们上面说的反射来获取 Unsafe类实例 private static final Unsafe unsafe = Unsafe.getUnsafe(); // AtomicInteger 里 value 值得 内存偏移地址 private static final long valueOffset; // 真正的 int 值 private volatile int value; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } public AtomicInteger(int initialValue) { value = initialValue; } public final int get() { return value; } /*** * 这段代码子在不加锁的情况下通过CAS 实现线程安全,我们设想下方法的执行: * 1. 假如 AtomicInteger原始值value为3,既 主存中值为3,根据java内存模型,线程1和线程2各自也拥有一份value的副本,值都是3 * * 2.线程1运行到 int current = get() 时,获取当前value的值为3 ,此时切换到线程2 * * 3.线程2开始运行,获取到的值也为3,利用CAS对比内存中的值为3,比较成功,修改了内存 ,此时内存的值变成修改后的4(假如),线程又切换 * * 4.线程1恢复,利用CAS比较 发现自己的值为3,内存的为4,得出一个结论:此时value正在被另一个线程修改,我不能修改它, CAS操作修改失败 * * 5.由于value是volatile的 ,所以某个时刻,主内存的值肯定会同步到线程1内的值, 所以代码用循环来执行CAS操作,直到值修改成功 */ public final int getAndSet(int newValue) { for (;;) { int current = get(); if (compareAndSet(current, newValue)) return current; } } // CAS 比较操作 ,看上面例子就能懂 public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }}
老生常谈:深圳有爱好音乐的会打鼓(吉他,键盘,贝斯等)的程序员和其它职业可以一起交流加入我们乐队一起嗨。我的QQ:657455400
阅读全文
1 0
- CAS AtomicInteger 源码解析
- java AtomicInteger 源码之CAS
- AtomicInteger源码解析
- AtomicInteger源码解析
- JDK7中AtomicInteger源码解析
- JDK 源码解析 —— AtomicInteger
- AtomicInteger的CAS原理
- AtomicInteger的CAS原理
- AtomicInteger源码
- AtomicInteger源码
- AtomicInteger解析
- Java并发编程AtomicInteger&CAS
- AtomicInteger源码分析——基于CAS的乐观锁实现
- Java 多线程:AtomicInteger源码分析——基于CAS的乐观锁实现
- Java 多线程:AtomicInteger源码分析——基于CAS的乐观锁实现
- AtomicInteger源码分析——基于CAS的乐观锁实现
- Memcached源码解析之cas属性
- CAS单点登录源码解析【目录】
- IIS配置error 500.24解决
- PAT 甲级 1015. Reversible Primes (20)
- 设置背景图片随着浏览器缩放保持不变
- 递归的运行过程
- 1.5多媒体技术的应用领域
- CAS AtomicInteger 源码解析
- 第三周-项目四(2)顺序表的应用
- [LintCode 363] 接雨水(Python)
- 一、多媒体技术的基础本章小结
- 排序算法--Java实现直接插入排序
- HDU 1241 Oil Deposits(递归,搜索)
- taberror inconsistent use of tabs and spaces in indentation pycharm
- CentOS设置系统时间与网络时间同步
- CentOS7引导Win7