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. 用nginx一分钟实现文件服务器

    在局域网内和同事共享文件的好方法 1 安装nginx sudo apt-get install nginx 2 创建conf文件 sudo gedit /etc/nginx/conf.d/file_s ...

  2. [LeetCode] Frog Jump 青蛙过河

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

  3. 在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证

    注:下载本文提到的完整代码示例请访问:How to authorization Angular 2 app with asp.net core web api 在ASP.NET Core中使用Angu ...

  4. 如何为Surface Dial设备开发自定义交互功能

    随着Surface Studio的发布,微软发布了与之相配套的外设硬件Surface Dial,用户可以将Surface Dail吸附在Surface Studio的屏幕上面,用旋转和点击的实体操作来 ...

  5. web前端开发中常用的尺寸和位置

    我们在日常web前端开发过程中,会经常用到各种尺寸和位置.通常是js做动画的时候.轮播图,滚屏动画,粒子,碰撞检测,拖拽,滚动加载等等.这里我将常用的尺寸和位置的获取进行总结,不包括canvas,SV ...

  6. CephRGW 在多个RGW负载均衡场景下,RGW 大文件并发分片上传功能验证

    http://docs.ceph.com/docs/master/radosgw/s3/objectops/#initiate-multi-part-upload 根据分片上传的API描述,因为对同一 ...

  7. Jenkins创建Maven项目及SSH部署

    前面我们已经安装了Jenkins的环境,以及配置好了jdk和maven.下面我们来看如何通过Jenkins将svn的项目进行打包和部署. 创建MAVEN项目 1.点击新建,输入项目名,选择" ...

  8. html你可能还不知道的一些知识点

    一.标签语义化 html标签语义化是让大家直观的认识标签和属性的用途和作用,好处最主要的是对搜索引擎友好. Eg: 1.如果你想在页面中突出"奥巴马"这三个字,让搜索引擎重视它,如 ...

  9. ES6深入学习记录(二)promise对象相关

    1.Promise的含义 Promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件更合理和强大.ES6将其写进了语言标准,统一了用法,原生提供了promise对象. 所谓Promis ...

  10. C#做有模和非模式化窗体 传值例程

    有模窗体:指的是一定要在第二个窗体上操作之后 才能去操作前者窗体 :例如,如果一个对话框,在可以切换到其它窗体或对话框之前要求先单击"确定"或"取消",则它就是 ...