`

[转]CAS的含义及Java中AtomicXXX类的分析

    博客分类:
  • java
阅读更多
维基百科:
In computer science, the compare-and-swap CPU instruction ("CAS") (or the Compare & Exchange - CMPXCHG instruction in the x86 and Itanium architectures) is a special instruction that atomically (regarding intel x86, lock prefix should be there to make it really atomic) compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a given new value. This guarantees that the new value is calculated based on up-to-date information; if the value had been updated by another thread in the meantime, the write would fail. The result of the operation must indicate whether it performed the substitution; this can be done either with a simple Boolean response (this variant is often called compare-and-set), or by returning the value read from the memory location (not the value written to it). Compare-and-Swap (and Compare-and-Swap-Double) has been an integral part of the IBM 370(and all successor) architectures since 1970. The operating systems which run on these architectures make extensive use of Compare-and-Swap (and Compare-and-Swap-Double) to facilitate process (i.e., system and user tasks) and processor (i.e., central processors) parallelism while eliminating, to the greatest degree possible, the "disabled spin locks" which were employed in earlier IBM operating systems. In these operating systems, new units of work may be instantiated "globally", into the Global Service Priority List, or "locally", into the Local Service Priority List, by the execution of a single Compare-and-Swap instruction. This dramatically improved the responsiveness of these operating systems.
===================================================
总结:CAS是硬件CPU提供的元语,它的原理:我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。
Java并发库中的AtomicXXX类均是基于这个元语的实现,以AtomicInteger为例:

public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

    public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}


其中,unsafe.compareAndSwapInt()是一个native方法,正是调用CAS元语完成该操作。
===================================================
顺便说下volatile。
根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有变量都储存在主存中,对于所有线程都是共享的。
每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。
所以,同一变量的值在工作内存和主存中可能不一致。volatile其实是告诉处理器, 不要将我放入工作内存, 请直接在主存操作我。
===================================================
回到AtomicInteger,注意到value的声明:

private volatile int value;


通过前面对volatile的介绍可以知道,直接对volatile的赋值和读取操作是无须加锁的,见源码:

public final int get() {
        return value;
}

public final void set(int newValue) {
        value = newValue;
}


注意:volatile的这种作用对double和long无效,因为JVM中将对double或long的赋值或读取操作拆成2个32位数的操作。
===================================================
那么,为什么自增操作要通过CAS来完成呢?仔细观察incrementAndGet()方法,发现自增操作其实拆成了两步完成的:

int current = get(); 
int next = current + 1;


由于valatile只能保证读取或写入的是最新值,那么可能出现以下情况:
1 A线程执行get()操作,获取current值(假设为1)
2 B线程执行get()操作,获取current值(为1)
3 B线程执行next = current + 1操作,next = 2
4 A线程执行next = current + 1操作,next = 2
这样的结果明显不是我们想要的,所以,自增操作必须采用CAS来完成。
分享到:
评论

相关推荐

    JAVA CAS深度分析

    2. CAS 操作的实现:JAVA 中的 CAS 操作通过 sun.misc.Unsafe 类的 compareAndSwapInt() 方法实现,该方法借助 JNI 调用 CPU 底层指令来实现 CAS 操作。 3. CAS 操作的应用:JAVA 中的 CAS 操作主要应用于 java.util...

    cas java cas java 实例

    在Java开发中,CAS扮演着重要角色,它简化了用户身份验证的过程,允许用户只需登录一次就能访问所有相互信任的应用系统。下面我们将详细探讨CAS的核心概念、工作原理以及如何在Java环境中实现和使用CAS。 1. CAS...

    Java CAS 原理分析

    在Java中,`AtomicInteger`类提供了基于CAS操作的方法,如`getAndIncrement()`,用于安全地递增一个整数值。 ```java AtomicInteger counter = new AtomicInteger(0); int newValue = counter.getAndIncrement(); /...

    cas客户端java版

    这些文件是CAS客户端库的核心组件,你需要将它们复制到你的Java应用的类路径(classpath)下,通常是项目的"lib"目录。 3. **配置CAS客户端**:在Java应用中,你还需要配置CAS客户端以连接到你的CAS服务器。这通常...

    Yale CAS SSO JAVA Client

    1. `cas-client-core-3.1.8.jar`:这是CAS Java客户端的核心库,包含了处理CAS协议交互所需的类和方法。它负责与CAS服务器通信,执行验证请求,处理服务票证(Service Ticket),并管理用户的会话状态。 2. `cas...

    java cas server 集成 java cas client 和 net client

    java cas server 集成 java cas client 和 net client 附带文档,问题解决方法,源码,jar包,包含技术有java cas,cfx,LDAP,net cas。核心在于集成了net client,,上传太小,不能传源码,有需要的加群。有兴趣的...

    java-cas客户端client安装包

    Java CAS 客户端是Java应用程序与中央认证服务(CAS)进行交互的一种工具,它使得在分布式环境中实现单点登录(Single Sign-On, SSO)成为可能。CAS 是一个开源项目,由耶鲁大学发起,旨在提供一种安全的Web身份验证...

    java/android连接CAS登陆验证工具类

    3、这是一个工具类调用非常方便,不光适用于java也适用于android, 其他语言也可以参考,注释写的非常清楚详细。 调用代码如下所示: boolean flag = validate("admin","123456",...

    CAS(SSO)-.zip_CAS_CAS SSO_java sso_sso java

    2. **CAS客户端集成**:如何在Java Web应用中集成CAS客户端库,设置过滤器以重定向未认证的请求到CAS服务器,以及解析返回的ST并验证。 3. **用户认证流程**:详细步骤解释了用户如何从登录到访问服务的整个过程,...

    Java--CAS操作分析.txt_python怎么分析txt

    根据提供的文件标题、描述、标签以及部分内容,本文将深入探讨Java中的CAS操作,并结合ConcurrentHashMap、ReentrantLock等核心概念进行分析。 ### Java中的CAS操作基础 在Java并发编程中,CAS(Compare and Swap...

    CAS单点登录(java)

    CAS单点登录(java)CAS单点登录(java)

    Yale CAS Server的部署及cas-java-client 3.2的应用

    《Yale CAS Server的部署及cas-java-client 3.2的应用》 CAS(Central Authentication Service,中央认证服务)是耶鲁大学开发的一个开源的身份验证框架,它为Web应用程序提供了单一登录(Single Sign-On,SSO)...

    cas实现单点登录,登出(java和php客户端)

    标题中的“CAS实现单点登录,登出(Java和PHP客户端)”指的是使用中央认证服务(Central Authentication Service,简称CAS)来构建一个跨域、跨平台的单点登录(Single Sign-On, SSO)系统。在这样的系统中,用户只...

    java LDAP+CAS单点登录

    在Java中,可以使用JNDI(Java Naming and Directory Interface)API来与LDAP服务器进行交互。 **CAS(Central Authentication Service)** CAS是一个开源的身份验证框架,由耶鲁大学开发,主要用于实现单点登录...

    CAS-SSO-TRIAL.zip_CAS_CAS SSO_java sso_sso

    在压缩包内的文件" CAS-SSO-TRIAL.doc"很可能是一个详细的文档,提供了关于如何设置和配置CAS服务器,以及如何在Java和.NET环境中实现SSO的步骤和指导。文档可能会涵盖以下关键知识点: 1. **CAS简介**:解释CAS的...

    java-cas单点登录服务端

    单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决...CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。

    CAS源码分析图

    CAS源码分析图,

    敏捷Acegi、CAS构建安全的Java系统(part2)共四part

    JAVA开发专家:敏捷Acegi、CAS:构建安全的Java系统 pdf

Global site tag (gtag.js) - Google Analytics