CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术。简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替换当前变量的值。这听起来可能有一点复杂但是实际上你理解之后发现很简单,接下来,让我们跟深入的了解一下这项技术。

CAS的使用场景

在程序和算法中一个经常出现的模式就是“check and act”模式。先检查后操作模式发生在代码中首先检查一个变量的值,然后再基于这个值做一些操作。下面是一个简单的示例:

01 class MyLock {
02  
03     private boolean locked = false;
04  
05     public boolean lock() {
06         if(!locked) {
07             locked = true;
08             return true;
09         }
10         return false;
11     }
12 }

上面这段代码,如果用在多线程的程序会出现很多错误,不过现在请忘掉它。

如你所见,lock()方法首先检查locked>成员变量是否等于false,如果等于,就将locked设为true。

如果同个线程访问同一个MyLock实例,上面的lock()将不能保证正常工作。如果一个线程检查locked的值,然后将其设置为false,与此同时,一个线程B也在检查locked的值,又或者,在线程A将locked的值设为false之前。因此,线程A和线程B可能都看到locked的值为false,然后两者都基于这个信息做一些操作。

为了在一个多线程程序中良好的工作,”check then act” 操作必须是原子的。原子就是说”check“操作和”act“被当做一个原子代码块执行。不存在多个线程同时执行原子块。

下面是一个代码示例,把之前的lock()方法用synchronized关键字重构成一个原子块。

01 class MyLock {
02  
03     private boolean locked = false;
04  
05     public synchronized boolean lock() {
06         if(!locked) {
07             locked = true;
08             return true;
09         }
10         return false;
11     }
12 }

现在lock()方法是同步的,所以,在某一时刻只能有一个线程在同一个MyLock实例上执行它。

原子的lock方法实际上是一个”compare and swap“的例子。

CAS用作原子操作

现在CPU内部已经执行原子的CAS操作。Java5以来,你可以使用java.util.concurrent.atomic包中的一些原子类来使用CPU中的这些功能。

下面是一个使用AtomicBoolean类实现lock()方法的例子:

1 public static class MyLock {
2     private AtomicBoolean locked = new AtomicBoolean(false);
3  
4     public boolean lock() {
5         return locked.compareAndSet(false, true);
6     }
7  
8 }

locked变量不再是boolean类型而是AtomicBoolean。这个类中有一个compareAndSet()方法,它使用一个期望值和AtomicBoolean实例的值比较,和两者相等,则使用一个新值替换原来的值。在这个例子中,它比较locked的值和false,如果locked的值为false,则把修改为true。

如果值被替换了,compareAndSet()返回true,否则,返回false。

使用Java5+提供的CAS特性而不是使用自己实现的的好处是Java5+中内置的CAS特性可以让你利用底层的你的程序所运行机器的CPU的CAS特性。这会使还有CAS的代码运行更快。

Java并发编程之CAS的更多相关文章

  1. Java并发编程之CAS第一篇-什么是CAS

    Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...

  2. Java并发编程之CAS二源码追根溯源

    Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...

  3. Java并发编程之CAS第三篇-CAS的缺点及解决办法

    Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...

  4. Java高性能编程之CAS与ABA及解决方法

    Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...

  5. Java并发编程之set集合的线程安全类你知道吗

    Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...

  6. Java并发编程之AQS

    一.什么是AQS AQS(AbstractQueuedSynchronize:队列同步器)是用来构建锁或者其他同步组件的基础框架,很多同步类都是在它的基础上实现的,比如常用的ReentrantLock ...

  7. Java 并发编程之 Condition 接口

    本文部分摘自<Java 并发编程的艺术> 概述 任意一个 Java 对象,都拥有一个监视器方法,主要包括 wait().wait(long timeout).notify() 以及 not ...

  8. Java并发编程之Lock

    重入锁ReentrantLock 可以代替synchronized, 但synchronized更灵活. 但是, 必须必须必须要手动释放锁. try { lock.lock(); } finally ...

  9. Java并发编程之synchronized关键字

    整理一下synchronized关键字相关的知识点. 在多线程并发编程中synchronized扮演着相当重要的角色,synchronized关键字是用来控制线程同步的,可以保证在同一个时刻,只有一个 ...

随机推荐

  1. keil uVision4一些使用总结(汉字注释,C关键字等)

    近日心血来潮,下载了最新的版的keil,再加上protues ,想弄个虚拟环境.主要原因还是经济问题.电子元件,是要花钱的... 今天遇到些keil uVision 4使用方面的问题,记录下来,方便以 ...

  2. MySql的卸载问题

    windows下mysql的卸载: 彻底卸载Mysql的方法:   (1),先在服务(开始——>控制面板——>管理工具——>服务)里停掉MySQL的服务.打开控制面板-添加删除程序, ...

  3. WordPress Comment Extra Fields插件‘swfupload.swf’跨站脚本漏洞

    漏洞名称: WordPress Comment Extra Fields插件‘swfupload.swf’跨站脚本漏洞 CNNVD编号: CNNVD-201308-027 发布时间: 2013-08- ...

  4. 【转】Java中字符串中子串的查找共有四种方法(indexof())

    原文网址:http://wfly2004.blog.163.com/blog/static/1176427201032692927349/ Java中字符串中子串的查找共有四种方法,如下:1.int ...

  5. Android安全bug ANDROID-8219321

    ANDROID-8219321漏洞主要源自Android ZipFile函数漏洞:没有进行校验重名entry逻辑漏洞,逻辑漏洞细节详见Google+文章和Bluebox Security提报Andro ...

  6. lightoj 1407 2-sat

    这题的英语either...or....很蛋疼: m中,1:x与y至少一个出席:2:x出席,y随便,x不出席,y也不出席----这有个坑,可以推出y出席x也一定出席(这个关系必须要连上):3x与y至少 ...

  7. 南京Uber优步司机奖励政策(1月11日~1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  8. Spring配置多个数据源

    Spring 配置多数据源实现数据库读写分离 博客分类: Spring 数据库   现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Mast ...

  9. msyql 字节问题

    MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0~255或1~255(根据不同版本数据库来定).在 MySQL5.0以上的版本中,varchar数据 ...

  10. 看小白如何解决ajax跨域问题

    由于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决ajax的跨域问题.本篇将讲述一个小白从遇到跨域不知道 ...