java并发编程之cas详解

 更新时间:2017年11月03日 15:12:35   投稿:mengwei  
这篇文章主要介绍了java并发编程之cas详解,涉及cas使用场景和cas用作原子操作等内容,具有一定参考价值,需要的朋友可以了解下。

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,然后两者都基于这个信息做一些操作。

为了在一个多线程程序中良好的工作,”checkthenact”操作必须是原子的。原子就是说”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的代码运行更快。

总结

以上就是关于java并发编程之cas详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Java系统的高并发解决方法详解Java并发编程之重入锁与读写锁Java并发编程Semaphore计数信号量详解等,有什么问题可以随时留言,欢迎您的宝贵意见,小编会及时回复大家的。感谢朋友们对本站的支持!

相关文章

  • SpringBoot集成ActiveMQ的实战全过程

    SpringBoot集成ActiveMQ的实战全过程

    消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题,实现高性能、高可用、可伸缩和最终一致性架构,是大型分布式系统不可缺少的中间件,这篇文章主要给大家介绍了关于SpringBoot集成ActiveMQ的相关资料,需要的朋友可以参考下
    2021-11-11
  • Java中的三种代理模式详解

    Java中的三种代理模式详解

    这篇文章主要介绍了Java中的三种代理模式详解,代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象,文中提供了部分代码,需要的朋友可以参考下
    2023-08-08
  • Java Web 实现QQ登录功能一个帐号同一时间只能一个人登录

    Java Web 实现QQ登录功能一个帐号同一时间只能一个人登录

    对于一个帐号在同一时间只能一个人登录,下文给大家介绍的非常详细,对java web qq 登录功能感兴趣的朋友一起看看吧
    2016-11-11
  • 浅析fastjson2时间序列化和反序列化的简单使用

    浅析fastjson2时间序列化和反序列化的简单使用

    在项目中将fastjson升级为fastjson2后,我们遇到了一些与fastjson不完全兼容的问题,所以本文就来探讨下fastjson2的时间序列化和反序列化的简单使用吧
    2025-01-01
  • Springboot添加支付接口

    Springboot添加支付接口

    这篇文章主要介绍了springboot如何添加支付接口,帮助大家更好得理解和学习使用springboot框架,感兴趣的朋友可以了解下
    2021-04-04
  • Java实现将数字日期翻译成英文单词的工具类实例

    Java实现将数字日期翻译成英文单词的工具类实例

    这篇文章主要介绍了Java实现将数字日期翻译成英文单词的工具类,结合完整实例形式分析了Java日期转换与字符串操作相关实现技巧,需要的朋友可以参考下
    2017-09-09
  • 基于mybatis注解动态sql中foreach工具的方法

    基于mybatis注解动态sql中foreach工具的方法

    这篇文章主要介绍了mybatis注解动态sql中foreach工具方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Spring中自定义拦截器的使用

    Spring中自定义拦截器的使用

    大家好,本篇文章主要讲的是Spring中自定义拦截器的使用,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • Java中获取文件大小的详解及实例代码

    Java中获取文件大小的详解及实例代码

    这篇文章主要介绍了Java中获取文件大小的详解及实例代码的相关资料,一种是使用File的length()方法,另外一种是使用FileInputStream的available()方法,这里就说下如何使用需要的朋友可以参考下
    2016-12-12
  • 关于Java集合框架面试题(含答案)下

    关于Java集合框架面试题(含答案)下

    Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点。这里,我列出了一些关于Java集合的重要问题和答案。
    2015-12-12

最新评论