`
flychao88
  • 浏览: 742339 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

深入理解并发之CompareAndSet(CAS)

 
阅读更多

一、CAS简介

CAS:Compare and Swap, 翻译成比较并交换。 

java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁,使用这些类在多核CPU的机器上会有比较好的性能.

 

CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

 

今天我们主要是针对AtomicInteger的incrementAndGet做深入分析。

 

二、JAVA实现部分

 

/**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

  循环的内容是
1.取得当前值
2.计算+1后的值
3.如果当前值没有被覆盖的话设置那个+1后的值
4.如果设置没成功, 再从1开始

 

在这个方法中可以看到compareAndSet这个方法,我们进入看一下。

/**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

 调用UnSafe这个类的compareAndSwapInt

  

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

 JAVA程序也就跟踪到这里为止了,剩下的就是通过JNI调用C程序了,可是我奇怪的是为什么变量名都是var1,var2这样的命名呢?JAVA编程规范不是说不使用1,2等没有含义的字符命名吗?

 

三、JNI原生实现部分

在openJDK中找到找到unsafe.cpp这个文件,代码如下:

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

 核心方法是compxchg,这个方法所属的类文件是在OS_CPU目录下面,由此可以看出这个类是和CPU操作有关,进入代码如下:

inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {
  // alternative for InterlockedCompareExchange
  int mp = os::is_MP();
  __asm {
    mov edx, dest
    mov ecx, exchange_value
    mov eax, compare_value
    LOCK_IF_MP(mp)
    cmpxchg dword ptr [edx], ecx
  }
}

 这个方法里面都是汇编指命,看到LOCK_IF_MP也有锁指令实现的原子操作,其实CAS也算是有锁操作,只不过是由CPU来触发,比synchronized性能好的多。

 

分享到:
评论

相关推荐

    01、从0开始深入理解并发、线程与等待通知机制(上

    01、从0开始深入理解并发、线程与等待通知机制(上01、从0开始深入理解并发、线程与等待通知机制(上01、从0开始深入理解并发、线程与等待通知机制(上01、从0开始深入理解并发、线程与等待通知机制(上01、从0开始...

    14、深入理解并发可见性、有序性、原子性与JMM内存模型

    深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发...

    03、从0开始深入理解并发、线程与等待通知机制(下

    03、从0开始深入理解并发、线程与等待通知机制(下03、从0开始深入理解并发、线程与等待通知机制(下03、从0开始深入理解并发、线程与等待通知机制(下03、从0开始深入理解并发、线程与等待通知机制(下03、从0开始...

    02、从0开始深入理解并发、线程与等待通知机制(中)

    02、从0开始深入理解并发、线程与等待通知机制(中)02、从0开始深入理解并发、线程与等待通知机制(中)02、从0开始深入理解并发、线程与等待通知机制(中)02、从0开始深入理解并发、线程与等待通知机制(中)02、...

    深入理解并发编程

    linux大神paul作品,详细介绍了并发编程的各种概念。内存屏障,mutex等。值得一读。

    01-并发编程之深入理解JMM&并发三大特性(一).pdf

    并发编程之深入理解JMM&并发三大特性

    Java 并发核心编程

    这篇指南主要是为帮助java多线程开发人员理解并发的核心概念以及如何应用这些理念。本文的主题是关于具有java语言风格的Thread、synchronized、volatile,以及J2SE5中新增的概念,如锁(Lock)、原子性(Atomics)、并发...

    JAVA并发编程学习笔记之CAS操作

     CAS是单词compare and set的缩写,意思是指在set之前先比较该值有没有变化,只有在没变的情况下才对其赋值。  我们常常做这样的操作  if(a==b) {  a++;  }  试想一下如果在做a++之前a的值被改变了...

    14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf

    14、深入理解井发可见性、有序性、原子性与JMM内存模型 (1).pdf 15、CPU缓存架构详解&高性能内存队列Disruptor 实战 (1).pdf 16、常用并发设计模式精讲 (1).pdf designpattern.zip disruptor.zip forkjoin.zip jmm(1...

    《深入理解 Rust 并发编程》

    是一本全面深入探讨 Rust 语言并发特性的指南。它从基础概念出发,逐步深入到高级话题,涵盖了线程、线程池、异步编程、同步原语等多个方面。书中不仅详细介绍了 Rust 标准库中的并发工具,还涉及了第三方库的使用,...

    从0开始深入理解并发、线程与等待通知机制

    从互联网公司的招聘需求可以看到,大厂的 Java 岗的并发编程能力属于标配。 而在非大厂的公司,并发编程能力也是面试的极大加分项, 而工作时善用并发编程则可以极大提升程序员在公司的技术话语权

    05、CAS详解和学透面试必问并发安全问题-ev

    05、CAS详解和学透面试必问并发安全问题_ev05、CAS详解和学透面试必问并发安全问题_ev05、CAS详解和学透面试必问并发安全问题_ev05、CAS详解和学透面试必问并发安全问题_ev05、CAS详解和学透面试必问并发安全问题_ev...

    深入理解分布式事务,高并发下分布式事务的解决方案

    本文来自于csdn,本文主要从分布式的原因,事务特性,和解决方案中深入理解了分布式事务,希望对您的学习有所帮助。 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的...

    深入理解高并发编程-Java线程池核心技术.rar

    深入理解高并发编程-Java线程池核心技术 全面详解Java线程池核心技术

    深入理解高并发下分布式事务的解决方案.docx

    深入理解高并发下分布式事务的解决方案.docx

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段04讲、多线程的休息室WaitSet详细介绍与知识点总结.mp4 │ 高并发编程第二阶段05讲、一个解释volatile关键字作用最好的例子.mp4 │ 高并发编程第二阶段06讲、Java内存模型以及CPU缓存不一致...

    并发编程概念理解

    帮助理解并发编程的基本认识,开启并发编程之旅。让同学们快速进并发世界

    Java高并发编程详解.md

    有关java高并发知识总结:三种线程创建方式 深入理解Thread构造函数 Thread API #### CAS缺陷 ##### 循环时间长开销大,自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。 ##### 只能保证一个共享变量...

    深入理解java7

    第二部分是7-13章,对JVM、Java源代码和字节代码操作、类加载器、对象生命周期、多线程、并发编程、泛型、安全等Java平台的核心技术进行了深入解析,掌握这部分内容有助于深入理解Java的底层原理;第三部分为第14章...

    深入理解Java并发之synchronized实现原理.docx

    线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。因此为了解决这个问题,我们可能需要这样一个方案,当...

Global site tag (gtag.js) - Google Analytics