AtomicReference介绍

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

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

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

  1.  
  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示例

  1.  
  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>

运行结果:

  1.  
  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原子类”04之 AtomicReference原子类

    概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...

  2. Java多线程系列目录(共43篇)

    最近,在研究Java多线程的内容目录,将其内容逐步整理并发布. (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线 ...

  3. Java多线程总结之线程安全队列Queue

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非 ...

  4. Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类

    概要 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法 ...

  5. Java多线程系列

    一.参考文献 1.:Java多线程系列目录 (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线程的两种方式 03. ...

  6. 【转】 Java 多线程之一

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

  7. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  8. Java多线程系列——原子类的实现(CAS算法)

    1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...

  9. Java多线程--锁的优化

    Java多线程--锁的优化 提高锁的性能 减少锁的持有时间 一个线程如果持有锁太长时间,其他线程就必须等待相应的时间,如果有多个线程都在等待该资源,整体性能必然下降.所有有必要减少单个线程持有锁的时间 ...

随机推荐

  1. GBK 字符集

    什么是 GBK ? 中文名 汉字编码字符集 外文名 Chinese Internal Code Specification 全    称 <汉字内码扩展规范> GBK编码,是对GB2312 ...

  2. Android RelativeLayout属性含义

    a).第一类:属性值为true或false android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android ...

  3. [译]MediatR, FluentValidation, and Ninject using Decorators

    原文 CQRS 我是CQRS模式的粉丝.对我来说CQRS能让我有更优雅的实现.它同样也有一些缺点:通常需要更多的类,workflow不总是清晰的. MediatR MediatR的文档非常不错,在这就 ...

  4. c# 适配器批量修改

    DataTable dt; //在方法外部申明数据表SqlDataAdapter adapter; //在方法外部申明数据适配器 查询方法adapter = new SqlDataAdapter(Sq ...

  5. 使用Python的turtle库画圣诞树

    代码如下: from turtle import * import random import time n = 80.0 speed("fastest") screensize( ...

  6. 5-4日 socket套接字

    1,socket定义 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...

  7. FTP之二

    username=admin password=123 ip=192.168.14.117 port=21 参考:http://blog.csdn.net/yelove1990/article/det ...

  8. Spring 源码分析 spring-core 篇

    先来看下 spring-core 的包结构 总共有6个模块,分别是 asm.cglib.core.lang.objenesis.util asm包: 用来操作字节码,动态生成类或者增强既有类的功能.主 ...

  9. python 数据分析2

    本节概要 Numpy详解 安装 Numpy的安装已经不想多说..在确保pip或pip3的路径被添加到系统环境变量里面之后,就可以直接用下面语句进行安装. pip install numpy or pi ...

  10. WIN10 困扰多时的屏幕亮度 终于可以调节了-完美 -更新2018年2月28日

    总结:很多问题是自己认知不够造成的,  -- 问题解决在  修复经历二,可直接跳过去看  修复经历二. 首先看你屏幕亮度是集成还是独立显卡决定的(一般是集成),所以下面 修复经历一折腾独立显卡驱动没什 ...