更多 Java 并发编程方面的文章,请参见文集《Java 并发编程》

AtomicReference

An object reference that may be updated atomically.

The AtomicReference class provides reference objects that may be read and written atomically, so when multiple threads try to reach them at the same time, only one will be able to do so.

提供了引用变量的读写原子性操作。

提供了如下的方法:

compareAndSet(V expect, V update):Atomically sets the value to the given updated value if the current value == the expected value.

getAndSet(V newValue):Atomically sets to the given value and returns the old value.

lazySet(V newValue):Eventually sets to the given value.

set(V newValue):Sets to the given value.

get():Gets the current value.

假设有一个类 Person,定义如下:

class Person {

private String name;

private int age;

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String toString() {

return "[name: " + this.name + ", age: " + this.age + "]";

}

}

如果使用普通的对象引用,在多线程情况下进行对象的更新可能会导致不一致性。例如:

一个对象的初始状态为 name=Tom, age = 18。

在 线程1 中将 name 修改为 Tom1,age + 1。

在 线程2 中将 name 修改为 Tom2,age + 2。

我们认为只会产生两种结果:

若 线程1 先执行,线程2 后执行,则中间状态为 name=Tom1, age = 19,结果状态为 name=Tom2, age = 21

若 线程2 先执行,线程1 后执行,则中间状态为 name=Tom2, age = 20,结果状态为 name=Tom1, age = 21

但是可能的输出如下:

Person is [name: Tom, age: 18]

Thread2 Values [name: Tom1, age: 21]

Thread1 Values [name: Tom1, age: 21]

Now Person is [name: Tom1, age: 21]

// 普通引用

private static Person person;

public static void main(String[] args) throws InterruptedException {

person = new Person("Tom", 18);

System.out.println("Person is " + person.toString());

Thread t1 = new Thread(new Task1());

Thread t2 = new Thread(new Task2());

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("Now Person is " + person.toString());

}

static class Task1 implements Runnable {

public void run() {

person.setAge(person.getAge() + 1);

person.setName("Tom1");

System.out.println("Thread1 Values "

+ person.toString());

}

}

static class Task2 implements Runnable {

public void run() {

person.setAge(person.getAge() + 2);

person.setName("Tom2");

System.out.println("Thread2 Values "

+ person.toString());

}

}

如果使用原子性对象引用,在多线程情况下进行对象的更新可以确保一致性。例如:

// 普通引用

private static Person person;

// 原子性引用

private static AtomicReference aRperson;

public static void main(String[] args) throws InterruptedException {

person = new Person("Tom", 18);

aRperson = new AtomicReference(person);

System.out.println("Atomic Person is " + aRperson.get().toString());

Thread t1 = new Thread(new Task1());

Thread t2 = new Thread(new Task2());

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("Now Atomic Person is " + aRperson.get().toString());

}

static class Task1 implements Runnable {

public void run() {

aRperson.getAndSet(new Person("Tom1", aRperson.get().getAge() + 1));

System.out.println("Thread1 Atomic References "

+ aRperson.get().toString());

}

}

static class Task2 implements Runnable {

public void run() {

aRperson.getAndSet(new Person("Tom2", aRperson.get().getAge() + 2));

System.out.println("Thread2 Atomic References "

+ aRperson.get().toString());

}

}

但是可能的输出如下:

Atomic Person is [name: Tom, age: 18]

Thread1 Atomic References [name: Tom1, age: 19]

Thread2 Atomic References [name: Tom2, age: 21]

Now Atomic Person is [name: Tom2, age: 21]

java 原子引用_Java 原子性引用 AtomicReference相关推荐

  1. java原子引用怎么理解_Java 原子性引用 AtomicReference

    AtomicReference An object reference that may be updated atomically. The AtomicReference class provid ...

  2. java reference 传引用_Java的引用(reference)---Roni

    摘自<Java面向对象编程>一书,作者:孙卫琴 来源:www.javathinker.org 在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说 ...

  3. java 幽灵引用_Java 幽灵引用的作用

    原标题:Java 幽灵引用的作用 来源:imzoer, blog.csdn.net/imzoer/article/details/8044900 找实习的时候,面试大摩,就遇到了这个问题,当时真不该跟 ...

  4. java改变实参_java中引用传递问题,在函数中修改引用的指向,会不会影响实参?...

    是时候展现一下我的JAVA基础知识了,2333. 我按照执行顺序给你写注释好了. Person p1 = new Person(10); //创建了一个对象 //p1.age=10; modify(p ...

  5. java超类 子类_Java超类引用子类对象的规律

    首先,对于JVM实现引用的一个机制是:类实例的引用就是指向一个句柄(handle)的指针,这个句柄就是一堆指针:一个指针指向一块从java堆中为分配出来内存空间:另一个指针指向一张表(实际上这个表格也 ...

  6. java的引用类型_JAVA类型(引用类型变量和使用)

    (1)用类名(相对于基本类型也可视为一种类型)来声明变量,这种变量叫引用类型变量.如:People people; (2)引用类型变量保存对象的引用(地址). (3)对象的创建及返回–new 类名() ...

  7. java的虚引用_java虚引用的使用说明

    "为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知." public static void main(String[] args) throws ...

  8. java 注释添加引用_java – 如何引用注释处理中的方法的实现?

    我正在玩Java(javax)注解处理. 假设我有一个注释的方法: @Target(ElementType.METHOD) public @interface MethodAnnotation { } ...

  9. java 原子数据类型_java并发编程(十一)----(JUC原子类)基本类型介绍

    上一节我们说到了基本原子类的简单介绍,这一节我们先来看一下基本类型: AtomicInteger, AtomicLong, AtomicBoolean.AtomicInteger和AtomicLong ...

最新文章

  1. MVC验证10-到底用哪种方式实现客户端服务端双重异步验证
  2. FreeBSD NTP 简单使用
  3. AtCoder AGC039F Min Product Sum (容斥原理、组合计数、DP)
  4. plsqldev远程连接mysql_PLSQL Developer连接远程Oracle数据库
  5. php获取其他php文件变量值,php 引入其他文件中的变量
  6. Could not find result map
  7. 问题 1073: 弟弟的作业
  8. Extjs可视化设计视频教程二
  9. pandas日常数据处理
  10. 程序员做到年薪60万也不去炫富,背后原因曝光,麻烦做个人吧
  11. usb 键盘码表_键盘鼠标对应码表-delphi键值
  12. ​七周二次课(5月7日)监控io性能、free命令、ps命令、查看网络状态、linux下抓包...
  13. ASP.NET MVC 使用dataTable(3)--更多选项参考
  14. 千图/千库/我图网/觅元素,终身会员来了!设计师的福利日!视觉运营室
  15. 【SENCHA TOUCH】Sencha Touch ExtJs 给 Button 添加图片(二)
  16. Windows Phone上的相机景深计算器
  17. 企业外贸出口业务流程图 进出口贸易流程细节
  18. 微信群总是有人发广告?我用Python写个机器人消灭他!
  19. 嵌入式pcb打造超薄降压模块让14500锂电池直接替代5号电池
  20. 虾神的csdn技术博客

热门文章

  1. mysql 配置路径
  2. 差异分析定位Ring 3保护模块
  3. seo网站优化如何写好文章
  4. 一个完整的iOS开发框架(Frameworks)-NimbusKit
  5. FVR420v试用感受之六!
  6. postman使用介绍
  7. [Python3网络爬虫开发实战] 1.7.1-Charles的安装
  8. Windows 2003下的Http 500错误
  9. Android 多线程及线程通信
  10. 乔布斯留给后人最宝贵的十条经验!