Java并发编程之CAS
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的代码运行更快。
转载自并发编程网 – ifeve.com本文链接地址: Java并发编程之CAS
Java并发编程之CAS的更多相关文章
- Java并发编程之CAS第一篇-什么是CAS
Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
- Java高性能编程之CAS与ABA及解决方法
Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...
- Java并发编程之set集合的线程安全类你知道吗
Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...
- Java并发编程之AQS
一.什么是AQS AQS(AbstractQueuedSynchronize:队列同步器)是用来构建锁或者其他同步组件的基础框架,很多同步类都是在它的基础上实现的,比如常用的ReentrantLock ...
- Java 并发编程之 Condition 接口
本文部分摘自<Java 并发编程的艺术> 概述 任意一个 Java 对象,都拥有一个监视器方法,主要包括 wait().wait(long timeout).notify() 以及 not ...
- Java并发编程之Lock
重入锁ReentrantLock 可以代替synchronized, 但synchronized更灵活. 但是, 必须必须必须要手动释放锁. try { lock.lock(); } finally ...
- Java并发编程之synchronized关键字
整理一下synchronized关键字相关的知识点. 在多线程并发编程中synchronized扮演着相当重要的角色,synchronized关键字是用来控制线程同步的,可以保证在同一个时刻,只有一个 ...
随机推荐
- 关于如何在BCB中使用CodeGuard
作者:深圳虫 来自:深圳虫网本文来自http://www.szbug.com/disparticle.aspID=4 一. 为什么写这篇东西自己在使用BCB5写一些程序时需要检查很多东西,例如内存泄漏 ...
- C 函数原型
int add(int,int);//add two int numbers and return it--- add function prototype; int main(int argc, c ...
- NodeJS制作爬虫全过程
这篇文章主要介绍了NodeJS制作爬虫的全过程,包括项目建立,目标网站分析.使用superagent获取源数据.使用cheerio解析.使用eventproxy来并发抓取每个主题的内容等方面,有需要的 ...
- 线性规划||网络流(费用流):COGS 288. [NOI2008] 志愿者招募
[NOI2008] 志愿者招募 输入文件:employee.in 输出文件:employee.out 简单对比 时间限制:2 s 内存限制:512 MB [问题描述] 申奥成功后,布布经过 ...
- 【模拟】Codeforces 710A King Moves
题目链接: http://codeforces.com/problemset/problem/710/A 题目大意: 国际象棋标准8X8棋盘,国王能往周围8个方向走.输入国王的位置,输出当前国王能往几 ...
- OpenGL图形管线和坐标变换
转:http://blog.csdn.net/zhulinpptor/article/details/5897102 1. OpenGL 渲染管线 OpenGL渲染管线分为两大部分,模型观测变换(Mo ...
- qemu kvm 虚拟化
虚拟化: KVM是一个基于Linux内核的虚拟机,属于完全虚拟化.虚拟机监控的实现模型有两类:监控模型(Hypervisor)和宿主机模型(Host-based).由于监控模型需要进行处理器调度,还需 ...
- winscp自动执行脚本
我们经常使用WinSCP工具通过sftp协议上传获取文件,本文描述通过bat批量处理文件. 首先,我们打开dos命令窗口使用 cd \d :D\WinSCP 打开WinSCP安装目录 上传文件: wi ...
- linux内网机器访问外网代理设置squid
公司一般出于安全考虑, 在同一局域网中只有一台机器可以访问外网,运维进行了整体的限制, 但是在后面的工作中,需要在机器上安装一些软件,及命令,所以其他的机器需要访问外网来简化工作, 但又不能打乱原有运 ...
- OpenRisc-43-or1200的IF模块分析
引言 “喂饱饥饿的CPU”,是计算机体系结构设计者时刻要考虑的问题.要解决这个问题,方法大体可分为两部分,第一就是利用principle of locality而引进的cache技术,缩短取指时间,第 ...