lock-free是一种基于原子变量类来构建的非阻塞同步算法。

比较并交换(compare-and-swap)

我们经常会先检查某项东西,然后对其进行修改,如if(X...) {X=...}。这种行为在多线程下并不是线程安全的。那我们该如何做呢?

一种方法是对操作进行加锁,如

synchornized(obj){

if(x>0){

x -=  10;

}

}

究其原因,是因为上面的操作是一个复合操作。我们是否可以通过某种不可分的方式来处理呢?...

几乎所有的现代处理器都包含了比较并交换(CAS)指令。CAS包含了3个操作数--需要读写内存的位置V、进行比较的值A和拟写入的新值,当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不会执行任何操作。通过CAS我们可以把这种“先检查后执行”行为作为一个不可分的整体来处理。在Java1.5之后,原子变量类中提供了这种操作。

下面写个简单取钱的例子,看看其在Java下的应用。账户有一定的余额(10000),在多线程下每个人一次可取4000。如果写的withDraw(long)线程不安全,则可能余额被减成负数。

public class AccountCAS extends Thread{
private Account account;
public AccountCAS(Account account){
super();
this.account = account;
} @Override
public void run() { try {
Thread.sleep(500);
account.withDraw(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
final int NUM = 5;
Account ac = new Account();
for(int i=0;i<NUM;++i){
new AccountCAS(ac).start();
}
} } class Account{
/**
* 余额
*/
private AtomicLong balance = new AtomicLong(10000); public void withDraw(long money){
long oldValue = balance.get();
if(oldValue>=money){
while(true){
if(balance.compareAndSet(oldValue, oldValue-money)){
System.out.println(Thread.currentThread().getName()+" withDraw:"+money);
break;
}
}
}
}
}

运行结果如下:

Thread-0 withDraw:4000

Thread-3 withDraw:4000

以上的Lock-free算法不需要加锁,通常包含以下几点:1.原子变量 2.循环 3.CAS 4.退出

lcok-free简易实现的更多相关文章

  1. .NET里简易实现AOP

    .NET里简易实现AOP 前言 在MVC的过滤器章节中对于过滤器的使用就是AOP的一个实现了吧,时常在工作学习中遇到AOP对于它的运用可以说是很熟练了,就是没想过如果自己来实现的话是怎么实现的,性子比 ...

  2. 在.Net中实现自己的简易AOP

    RealProxy基本代理类 RealProxy类提供代理的基本功能.这个类中有一个GetTransparentProxy方法,此方法返回当前代理实例的透明代理.这是我们AOP实现的主要依赖. 新建一 ...

  3. .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”

    FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...

  4. 自己来实现一个简易的OCR

    来做个简易的字符识别 ,既然是简易的 那么我们就不能用任何的第三方库 .啥谷歌的 tesseract-ocr, opencv 之类的 那些玩意是叼 至少图像处理 机器视觉这类课题对我这种高中没毕业的人 ...

  5. php+websocket搭建简易聊天室实践

    1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短 ...

  6. 用Go实现的简易TCP通信框架

    接触到GO之后,GO的网络支持非常令人喜欢.GO实现了在语法层面上可以保持同步语义,但是却又没有牺牲太多性能,底层一样使用了IO路径复用,比如在LINUX下用了EPOLL,在WINDOWS下用了IOC ...

  7. .NET里简易实现IoC

    .NET里简易实现IoC 前言 在前面的篇幅中对依赖倒置原则和IoC框架的使用只是做了个简单的介绍,并没有很详细的去演示,可能有的朋友还是区分不了依赖倒置.依赖注入.控制反转这几个名词,或许知道的也只 ...

  8. MVC 验证码实现( 简易版)

    现在网站上越来越多的验证码,使用场景也是越来越多,登陆.注册.上传.下载...等等地方,都有可能大量使用到验证码,那么制作验证码到底有多简单呢?我们一起来看下最简易版的验证码实现过程- 验证码的基本步 ...

  9. 基于 getter 和 setter 撸一个简易的MVVM

    Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...

  10. nginx简易教程

    概述 什么是nginx? Nginx (engine x) 是一款轻量级的Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse Pr ...

随机推荐

  1. APUE学习之出错处理

         当UNIX函数发生错误时,通常会返回一个负值,而且整形变量errno通常被设置为具有特定信息的值.        errno是全局变量,仅当函数出错才有被改变.对待errno,应注意两条规则 ...

  2. 【推荐】CentOS安装PHP-5.6.4+扩展安装+安全配置+性能配置

    注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. #准备工作# 前段时间PHP官方发布了一个重要的安全升级公告,修复了两个unserialize函数的严重漏洞,目前受影响的版本有: ...

  3. win8改win7笔记

    内存<=4G,选32位(×86)   内存>=4G,选64位(×64)   (非必须) BIOS设置    USB Boot Support     Disabled改为Enabled(如 ...

  4. socket Bio demo

    最近在做socket通信,最开始是基于Bio开发(其实开发的时候也不知道这种是基于BIO).但是问题来了,客户端发的报文,服务端接收会少,为了解决问题,只能恶补一下相关知识. 服务端: import ...

  5. 深度优先搜索(DFS)

    [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...

  6. [LeetCode] Ternary Expression Parser 三元表达式解析器

    Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...

  7. [LeetCode] Ransom Note 赎金条

    
Given
 an 
arbitrary
 ransom
 note
 string 
and 
another 
string 
containing 
letters from
 all 
th ...

  8. 关于 bind 你可能需要了解的知识点以及使用场景

    不看不知道,一看吓一跳,已经整整一个月没有更新 underscore 源码解读系列文章了.前面我们已经完成了 Object ,Array,Collection 上的扩展方法的源码剖析,本文开始来解读 ...

  9. ASP.NET提取多层嵌套json数据的方法

    本文实例讲述了ASP.NET利用第三方类库Newtonsoft.Json提取多层嵌套json数据的方法,具体例子如下. 假设需要提取的json字符串如下: {"name":&quo ...

  10. Extjs 下拉框显示远程数据

    var store = new HT.SyncStore({ baseParams : { itemName : '绩效考核_任务状态' }, url : __ctxPath + '/system/l ...