前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >猫头鹰的深夜翻译:Java中的CAS(Compare And Swap)

猫头鹰的深夜翻译:Java中的CAS(Compare And Swap)

作者头像
眯眯眼的猫头鹰
发布2018-10-31 11:19:40
5290
发布2018-10-31 11:19:40
举报

题目要求

在我们深入了解CAS(Compare And Swap)策略以及它是如何在AtomicInteger这样的原子构造器中使用的,首先来看一下这段代码:

代码语言:javascript
复制
public class MyApp
{
    private volatile int count = 0;
    public void upateVisitors() 
    {
       ++count; //increment the visitors count
    }
}

这里的代码记录的访问应用的访客的数量。这段代码有问题么?如果多个线程试图更新这个数值会发生什么?事实上,这里的问题在于单单将count标记为volatile并不能保证原子性,++count也不是一个原子操作。想要了解更多请查看这里

那么如果我们将方法标记为synchronized可以解决这个问题吗?

代码语言:javascript
复制
public class MyApp
{
    private int count = 0;
    public synchronized void upateVisitors() 
    {
       ++count; //increment the visitors count
    }
}

这段代码可以保证原子性吗?可以。 这段代码可以保证可见性啊?可以。

那这里还有什么问题?

它使用了锁从而引入了大量的延时和。详情查看这里。这种方式开销太大。

为了解决这个问题引入了原子构造器。如果我们使用AtomicInteger来记录访问量,也可以达到目的。

代码语言:javascript
复制
public class MyApp
{
    private AtomicInteger count = new AtomicInteger(0);
    public void upateVisitors() 
    {
       count.incrementAndGet(); //increment the visitors count
    }
}

支持原子操作的类如AtomicInteger,使用CAS来实现。CAS并没有使用锁,而是以一种很乐观的方式来处理。它遵循以下几步:

  • 比较原始的值和我们已经获得的值
  • 如果这两个值不同,说明中间有线程改变了值。否则它就会用新的值替代当前值。

看一下AtomicLong类中的代码:

代码语言:javascript
复制
public final long incrementAndGet() {
    for (;;) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next))
          return next;
    }
}

在JDK 8中上面的代码被更改为一行代码:

代码语言:javascript
复制
public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}

这一行代码有何优点?

实际上,这一行是会由JIT翻译为优化的指令序列的JVM内部函数。在x86架构中它就是一条CPU指令LOCK XADD,会比CAS循环的性能好很多。

现在考虑一下当我们有较高的争用以及一些线程想要更​​新相同的原子变量的可能性。在这种情况下,锁可能会优于原子变量,但在实际的争用级别中,原子变量的性能优于锁。在Java 8 中引入了另外一个构件LongAdder

LongAdder并不完全是AtomicLong的替代品,我们需要考虑以下因素:

  • 当没有争用时,AtomicLong性能更好
  • LongAdder将分配Cells(在抽象类Striped64中声明的final类)以避免消耗内存的争用。所以如果我们有一个紧张的内存预算,我们应该更倾向于使用AtomicLong。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目要求
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档