AtomicReference介绍

AtomicReference是作用是对"对象"进行原子操作。

AtomicReference源码分析(基于JDK1.7.0_40)

在JDK1.7.0_40中AtomicReference.java的源码如下:

[java] view plaincopy
  1. public class AtomicReference<V>  implements java.io.Serializable {
  2. private static final long serialVersionUID = -1848883965231344442L;
  3. // 获取Unsafe对象,Unsafe的作用是提供CAS操作
  4. private static final Unsafe unsafe = Unsafe.getUnsafe();
  5. private static final long valueOffset;
  6. static {
  7. try {
  8. valueOffset = unsafe.objectFieldOffset
  9. (AtomicReference.class.getDeclaredField("value"));
  10. } catch (Exception ex) { throw new Error(ex); }
  11. }
  12. // volatile类型
  13. private volatile V value;
  14. public AtomicReference(V initialValue) {
  15. value = initialValue;
  16. }
  17. public AtomicReference() {
  18. }
  19. public final V get() {
  20. return value;
  21. }
  22. public final void set(V newValue) {
  23. value = newValue;
  24. }
  25. public final void lazySet(V newValue) {
  26. unsafe.putOrderedObject(this, valueOffset, newValue);
  27. }
  28. public final boolean compareAndSet(V expect, V update) {
  29. return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
  30. }
  31. public final boolean weakCompareAndSet(V expect, V update) {
  32. return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
  33. }
  34. public final V getAndSet(V newValue) {
  35. while (true) {
  36. V x = get();
  37. if (compareAndSet(x, newValue))
  38. return x;
  39. }
  40. }
  41. public String toString() {
  42. return String.valueOf(get());
  43. }
  44. }<span style="font-family: 'Courier New' !important; font-size: 12px !important; line-height: 1.5 !important; color: rgb(0, 0, 0);"></span>

说明:
AtomicReference的源码比较简单。它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
(01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
(02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。

AtomicReference示例

[java] view plaincopy
  1. // AtomicReferenceTest.java的源码
  2. import java.util.concurrent.atomic.AtomicReference;
  3. public class AtomicReferenceTest {
  4. public static void main(String[] args){
  5. // 创建两个Person对象,它们的id分别是101和102。
  6. Person p1 = new Person(101);
  7. Person p2 = new Person(102);
  8. // 新建AtomicReference对象,初始化它的值为p1对象
  9. AtomicReference ar = new AtomicReference(p1);
  10. // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。
  11. ar.compareAndSet(p1, p2);
  12. Person p3 = (Person)ar.get();
  13. System.out.println("p3 is "+p3);
  14. System.out.println("p3.equals(p1)="+p3.equals(p1));
  15. }
  16. }
  17. class Person {
  18. volatile long id;
  19. public Person(long id) {
  20. this.id = id;
  21. }
  22. public String toString() {
  23. return "id:"+id;
  24. }
  25. }<span style="font-family: 'Courier New' !important; font-size: 12px !important; line-height: 1.5 !important; color: rgb(0, 0, 0);"></span>

运行结果:

[java]
  1. p3 is id:102
  2. p3.equals(p1)=false<span style="font-family: 'Courier New' !important; font-size: 12px !important; line-height: 1.5 !important; color: rgb(0, 0, 255);"></span>

结果说明:
新建AtomicReference对象ar时,将它初始化为p1。
紧接着,通过CAS函数对它进行设置。如果ar的值为p1的话,则将其设置为p2。
最后,获取ar对应的对象,并打印结果。p3.equals(p1)的结果为false,这是因为Person并没有覆盖equals()方法,而是采用继承自Object.java的equals()方法;而Object.java中的equals()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。

java多线程--AtomicReference相关推荐

  1. Java多线程系列--“JUC原子类”01之 框架

    2019独角兽企业重金招聘Python工程师标准>>> Java多线程系列--"JUC原子类"01之 框架 根据修改的数据类型,可以将JUC包中的原子操作类可以分 ...

  2. Java多线程知识小抄集(二)

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  3. Java 多线程 并发编程

    转载自  Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...

  4. 40个问题让你快速掌握Java多线程的精髓

    本文分享自华为云社区<对Java多线程的用法感到一头乱麻?40个问题让你快速掌握多线程的精髓>,原文作者:breakDraw . 多线程可以理解为在同一个程序中能够同时运行多个不同的线程来 ...

  5. 万字图解Java多线程,不信你学不会!

    来源:Java面试题精选 前言 java多线程我个人觉得是javaSe中最难的一部分,我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程a ...

  6. java多线程学习笔记。

    java多线程学习笔记 线程的优缺点: 多线程的好处: 充分利用多处理核心,提高资源的利用率和吞吐量. 提高接口的响应效率,异步系统工作. 线程的风险: 安全危险(竞争条件):什么坏事都没有发生.在没 ...

  7. Java多线程--概述-转自Kyrie lrving

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  8. java多线程高级:JUC

    文章目录 java多线程高级:JUC 1 多线程锁 1.1 传统synchronized 1.2 Lock接口 1.3 Synchronized和Lock的区别 2生产者和消费者问题 2.1 Sync ...

  9. 2021全新Java多线程并发入门到精通,一篇就能学会

    目录 一, JAVA 多线程并发 1,JAVA 并发知识库 2,JAVA 线程实现/创建方式 (1) 继承 Thread 类 (2)实现 Runnable 接口. (3)ExecutorService ...

最新文章

  1. 购买过php,【已解决】PHP项目需求:用户购买商品时,给上级发送一条通知(无限级下级会员)...
  2. 安装php报错误2356,linux下Mysql+php5+apache安装手记
  3. property的修饰符
  4. jms spring_JMS和Spring:有时很重要的小事情
  5. webjs求数组的中位数‘_算法:一道常见的数组题,但很多人却写不出来(JAVA)...
  6. Bootstrap HTML 编码规范之布尔型属性
  7. Python: subprocess.Popen()不支持unicode问题解决
  8. spyder里import tensorflow报错显示没有tensorflow模块解决
  9. Tensorflow2.0实战之Auto-Encoder
  10. gotoxy函数定义
  11. 最强半自动化抓鸡工具打造思路
  12. java 传智播客 毕向东_传智播客:毕向东Java基础视频教程(全5)压缩包电驴下载...
  13. Mac墨刀怎么导出HTML,mockingbot墨刀中文使用说明.pdf
  14. web大作业介绍自己的家乡_中国10大乡村名鸭!快来看看自己家乡的鸭子是否上榜...
  15. 漂亮的表格样式(使用CSS样式表控制表格样式)
  16. logstash的lumberjack协议解析
  17. c++数独游戏3.3
  18. CSS基础(11)- 浮动
  19. h5 html页面百度定位当前位置不准
  20. FS78P372N单片机替代义隆EM78P372N

热门文章

  1. VMware中为linux设置网络
  2. Git常用的基本命令
  3. 7-19晚牛客网刷题未知点、错题 集合
  4. ios查看ipa是否函数特定字符_iOS 中基础字符判断函数收集(如判断大小写、数字等)...
  5. r语言plot函数x轴y轴名字_Matplotlib入门-1-plt.plot( )绘制折线图
  6. 神策 2021 数据驱动大会,科特勒、桑文锋等发出营销未来之强音
  7. 神策数据王琛:用户画像实践之神策标签生产引擎架构
  8. 百果园付凌峰:线上单月 1.2 亿背后的数据化运营
  9. 有一天老板和我要几个关键数据……
  10. Ubuntu 修改mysql存放路径后无法启动解决办法