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

    更多 Java 并发编程方面的文章,请参见文集<Java 并发编程> AtomicReference An object reference that may be updated ato ...

  2. java 父类引用子类对象_java 父类引用指向子类对象

    1. 无论是泛型还是普通父类引用指向子类对象,父类引用可见范围都是父类自己的变量或函数 2. 说明见注释 代码如下:父类 package com.atguigu.spring.beans; publi ...

  3. java常量池的理解_Java常量池的大概理解

    转载自:http://www.cnblogs.com/iyangyuan/p/4631696.html 理论 小菜先拙劣的表达一下jvm虚拟内存分布: 程序计数器是jvm执行程序的流水线,存放一些跳转 ...

  4. 对java支持并发的理解_Java并发知识(1)

    1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和 ...

  5. java 线程池的理解_JAVA线程池原理的理解

    线程池原理基础理解: 线程池初始化规定个数的线程,然后这些线程一直运行,并且监控线程队列,只要线程队列被添加进线程,那么线程池不断从队列中取出线程运行.直到队列中的线程为空.实例代码如下: packa ...

  6. java的多态怎么理解_JAVA多态的理解

    面向对象的三大特性:封装.继承.多态,其中最难理解的就是多态 以下是网上某大神给的一个例子: 1.继承关系 class A { public String show(D obj){ return (& ...

  7. java的静态如何理解_java中的静态是什么?如何理解?

    在Java语言中,static表示"静态"的意思,使用场景可以用来修饰成员变量和成员方法,当然也可以是静态代码块.static的主要作用在于创建独立于具体对象的域变量或者方法. 格 ...

  8. java中逻辑运算符怎么理解_java 逻辑运算符理解

    1.1 逻辑运算符 逻辑运算符,它是用于布尔值进行运算的,运算的最终结果为布尔值true或false. 运算符 运算规则 范例 结果 & 与 false&true False | 或 ...

  9. 看完这个你还不理解右值引用和移动构造 你就可以来咬我(上)

    共分三篇,这是第一篇.另外两篇,看完这个你还不理解右值引用和移动构造 你就可以来咬我(中),看完这个你还不理解右值引用和移动构造 你就可以来咬我(下). C++ 右值引用 & 新特性 C++ ...

最新文章

  1. boost库 tbb_c++ 最简单的TBB示例
  2. 漫画 | 一台 Linux 服务器最多能支撑多少个 TCP 连接?
  3. 【按住你的心】——Android开发CheckBoxRadioButton控件的简单使用
  4. Excel制作考勤管理
  5. python3 requests获取网页cookie并打印
  6. 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇
  7. 优化 .net core 应用的 dockerfile
  8. python中range函数是什么意思_python里range是什么
  9. SonarQube搭建和使用教程
  10. oracle ogg 删除,OGG导致归档无法RMAN删除一例
  11. python语言中有3种表示字符串的方式、单引号和_Python中三种类型的引号(单引号、双引号、三引号)...
  12. 将一个对象的空值全部设置为null
  13. matlab 计算矩阵a的离散余弦变换
  14. python 读取excel表格的数据
  15. ELK 学习笔记之 elasticsearch Bulk操作
  16. Java课程设计——学生成绩管理系统
  17. 利用沙盒技术破解APP的API协议加密
  18. 搜狗输入法纯净_输入法纯净,你其实只差个补丁
  19. Ubuntu输入简体中文变成繁体
  20. 先天八卦图的排列顺序,这样来解释您能接受吗?

热门文章

  1. 【学习】程序员技术练级攻略
  2. 数据范围BZOJ 3209(花神的数论题-数位统计+1,被数据范围坑了)
  3. 详解C#break ,continue, return
  4. 如何修改webbrowser里的JS函数
  5. sendmessage和postmessage的区别
  6. NopCommerce开源项目中很基础但是很实用的C# Helper方法
  7. Maven编译代码的相关命令
  8. Backbone源码分析-Backbone架构+流程图
  9. 异星工厂 自动机器人_插件机机器人能够实现工厂自动化
  10. springboot中使用poi导出excel文件(亲测实现了第一个功能)