以下内容转自http://ifeve.com/compare-and-swap/

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

CAS的使用场景

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

class MyLock {

    private boolean locked = false;

    public boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}

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

如你所见,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关键字重构成一个原子块。

class MyLock {

    private boolean locked = false;

    public synchronized boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}

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

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

CAS用作原子操作

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

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

public static class MyLock {
private AtomicBoolean locked = new AtomicBoolean(false); public boolean lock() {
return locked.compareAndSet(false, true);
} }

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

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

27、Java并发性和多线程-CAS(比较和替换)的更多相关文章

  1. java 并发性和多线程 -- 读感 (一 线程的基本概念部分)

    1.目录略览      线程的基本概念:介绍线程的优点,代价,并发编程的模型.如何创建运行java 线程.      线程间通讯的机制:竞态条件与临界区,线程安全和共享资源与不可变性.java内存模型 ...

  2. Java 并发和多线程(一) Java并发性和多线程介绍[转]

    作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时 ...

  3. Java并发性和多线程

    Java并发性和多线程介绍   java并发性和多线程介绍: 单个程序内运行多个线程,多任务并发运行 多线程优点: 高效运行,多组件并行.读->操作->写: 程序设计的简单性,遇到多问题, ...

  4. Java并发性和多线程介绍

    java并发性和多线程介绍: 单个程序内运行多个线程,多任务并发运行 多线程优点: 高效运行,多组件并行.读->操作->写: 程序设计的简单性,遇到多问题,多开线程就好: 快速响应,异步式 ...

  5. Java高级教程:Java并发性和多线程

    Java并发性和多线程: (中文,属于人工翻译,高质量):http://ifeve.com/java-concurrency-thread-directory/ (英文):http://tutoria ...

  6. Java 并发性和多线程

    一.介绍 在过去单 CPU 时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个 ...

  7. 1、Java并发性和多线程-并发性和多线程介绍

    以下内容转自http://ifeve.com/java-concurrency-thread/: 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行 ...

  8. 6、Java并发性和多线程-并发性与并行性

    以下内容转自http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html(使用谷歌翻译): 术语并发和并行性 ...

  9. 29、Java并发性和多线程-非阻塞算法

    以下内容转自http://ifeve.com/non-blocking-algorithms/: 在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在 ...

随机推荐

  1. 转 MySQL数据库基础

    http://lib.csdn.net/article/mysql/57883 1 数据库基础 一.数据库与数据库管理系统 1.数据库(DB):存放数据的仓库,从广义来说,数据不仅包括数字,还包括了文 ...

  2. JS在即将离开当前页面(刷新或关闭)时触发事件

    // onbeforeunload 事件在即将离开当前页面(刷新或关闭)时触发 window.onbeforeunload = function () { return /^\#\/ipinfo/.t ...

  3. IFormattable,ICustomFormatter, IFormatProvider接口

    定                 义 1.IFormattable   提供一种功能,用以将对象的值格式化为字符串表示形式. 2.IFormatProvider  提供用于检索控制格式化的对象的机制 ...

  4. 学习笔记 第五章 使用CSS美化网页文本

    第五章   使用CSS美化网页文本 学习重点 定义字体类型.大小.颜色等字体样式: 设计文本样式,如对齐.行高.间距等: 能够灵活设计美观.实用的网页正文版式. 5.1 字体样式 5.1.1 定义字体 ...

  5. Ubuntu下查看服务器cpu是否支持VT

    http://blog.51cto.com/zhangmingqian/1249522 Ubuntu下查看服务器cpu是否支持VT 原创wazjajl 2013-07-15 16:25评论(0)119 ...

  6. 清除浮动(float)的影响

    浮动会导致父元素塌陷如图: 解决办法: 父元素overflow:hidden,如图 末尾插入子元素clear,如图 为甚么,父元素overflow:hidden会解决塌陷问题? 来自知乎貘吃馍香的回答 ...

  7. 【C++】智能指针简述(五):解决循环引用的weak_ptr

    总结一下前文内容: 1.智能指针通过RAII方法来管理指针:构造对象时,完成资源初始化;析构对象时,对资源进行清理及汕尾. 2.auto_ptr,通过“转移所有权”来防止析构一块内存多次.(如何转移? ...

  8. C# 绘图三种方式

    如果你想在窗体上进行绘画.通常会使用以下方法. 方法1,利用控件或窗体的paint事件中的painEventArgs private void form1_Paint(object sender, P ...

  9. 12Java Bean

     Java Bean JavaBean是一种组件体系结构.实际上,JavaBean就是一个Java类,这个类可以重复地使用.我们可以把JavaBean看成是一个黑盒子,即只需要知道其功能而不必管其内部 ...

  10. SSH命令行传输文件到远程服务器

    Ubuntu操作系统 SCP命令 使用方式如下: 1.上传本地文件到远程服务器 scp /var/www/test.php root@192.168.0.101:/var/www/ 把本机/var/w ...