题目要求

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

public class MyApp
{private volatile int count = 0;public void upateVisitors() {++count; //increment the visitors count}
}

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

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

public class MyApp
{private int count = 0;public synchronized void upateVisitors() {++count; //increment the visitors count}
}

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

那这里还有什么问题?

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

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

public class MyApp
{private AtomicInteger count = new AtomicInteger(0);public void upateVisitors() {count.incrementAndGet(); //increment the visitors count}
}

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

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

看一下AtomicLong类中的代码:

public final long incrementAndGet() {for (;;) {long current = get();long next = current + 1;if (compareAndSet(current, next))return next;}
}

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

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。


想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~

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

  1. Java中的CAS(compare and swap)

    定义: 拿着寄存器/某个内存 中的值和另外一个内存的值进行比较,如果值相同了,就把两者交换 boolean CAS(address, expectValue, swapValue){if(&a ...

  2. 【高并发】java中的CAS,你需要知道的东西

    1.概述 转载:添加链接描述 从网站计数器实现中一步步引出CAS操作 介绍java中的CAS及CAS可能存在的问题 悲观锁和乐观锁的一些介绍及数据库乐观锁的一个常见示例 使用java中的原子操作实现网 ...

  3. 【面试篇】Java多线程并发-Java中的CAS机制算法

    Java中的CAS机制算法 a.CAS例子 再讲解CAS机制之前,先来看一道经典的并发执行1000次递增的问题: public class Test { public static int count ...

  4. JAVA 中的 CAS

    原文地址:https://www.xilidou.com/2018/02/01/java-cas/ CAS 是现代操作系统,解决并发问题的一个重要手段,最近在看 eureka 的源码的时候.遇到了很多 ...

  5. Java中的CAS操作

    Java中的CAS的含义 CAS即是Compare and Swap ,它是JDK提供的非阻塞原子性操作,它通过硬件保证了比较一更新操作的原子性.CAS 操作包含三个操作数-内存位置(V).预期原值( ...

  6. Java中的CAS以及AQS实现原理

    Java中的CAS实现原理 什么是CAS? 在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令. 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将 ...

  7. 什么是java中的CAS

    问题一:java中的CAS是什么? 问题二:为什么要使用CAS? 问题三:CAS使用中需要注意什么问题? 这里以提问的方式引出话题,下面带大家慢慢了解CAS. 1.CAS的含义 CAS是compare ...

  8. 猫头鹰的深夜翻译:在JAVA中记录日志的十个小建议

    前言 首先,这篇文章没有进行任何的日志功能的详细介绍,而是对日志提出了几种最佳实践.适合对日志记录有所了解的同学阅读. 下面是正文: JAVA日志管理既是一门科学,又是一门艺术.科学的部分是指了解写日 ...

  9. 猫头鹰的深夜翻译:在JVM上根据合约编程

    前言 这周我准备介绍一个有趣的但是很少使用的方法 按照合约编程,又称为合约编程,是一种软件设计的方法.它规定了软件设计师应该为软件组件定义正式,精确和可验证的接口规范,将常规的抽象数据类型扩展为前置条 ...

最新文章

  1. 为Android运行新的英特尔模拟器
  2. Java中的System.out.println到底是什么,而且Java源码中System.java的out是null,为什么可以调用println方法?
  3. 一段简单的JavaScript代码,实现在同一网页输出多个图标的功能
  4. 网页设计DIV+CSS——第7天:CSS入门
  5. 摆脱剧荒!教你用 Python 一步步爬取豆瓣电影新榜单
  6. python 字典嵌套列表 循环打印_python的list的基本操作、list循环、切片、字典基本操作、字典嵌套、字符串常用方法...
  7. python卷积神经网络预测股价_解读:一种基于CNN-LSTM混合神经网络的股价预测模型...
  8. 跑步到底伤不伤膝盖?励建安教授给你权威解答
  9. 讲讲自己试用期被劝退的经历!
  10. 单例模式——国庆收心
  11. AKM项目轶事之与高中同学徐挺会见
  12. 【零基础小白的华丽蜕变】Oracle WebLogic Server 14c(14.1.1.0)下载及安装
  13. uci数据集中的缺失数据_从uci早期糖尿病风险预测数据集中创建分类器
  14. 【1034】计算三角形面积
  15. vbs恶搞程序(超初级)
  16. 如何在 fibos 上创建快照和使用快照启动节点
  17. ASP.NET动态加载CSS文件
  18. Python可以自学吗?
  19. 教你如何在Linux系统安装软件
  20. mac nginx映射ip和端口_mac 上配置 nginx 端口转发访问 angular 项目

热门文章

  1. 作为前端,你需要懂得javascript实现继承的方法
  2. Promise(异步处理-实现)
  3. linux 上管理mysql_Linux下管理MySql
  4. c语言递归算法实验报告,递归算法实验报告.docx
  5. CMOS Sensor的调试经验分享(转)
  6. ARM Cotex-M4数据手册4---System Control
  7. java string类型的初始化
  8. Android实现登录
  9. CentOS工作内容(二)关闭SELinux
  10. 如何让service不被系统杀掉