java多线程--AtomicReference
AtomicReference介绍
AtomicReference是作用是对"对象"进行原子操作。
AtomicReference源码分析(基于JDK1.7.0_40)
在JDK1.7.0_40中AtomicReference.java的源码如下:
- public class AtomicReference<V> implements java.io.Serializable {
- private static final long serialVersionUID = -1848883965231344442L;
- // 获取Unsafe对象,Unsafe的作用是提供CAS操作
- private static final Unsafe unsafe = Unsafe.getUnsafe();
- private static final long valueOffset;
- static {
- try {
- valueOffset = unsafe.objectFieldOffset
- (AtomicReference.class.getDeclaredField("value"));
- } catch (Exception ex) { throw new Error(ex); }
- }
- // volatile类型
- private volatile V value;
- public AtomicReference(V initialValue) {
- value = initialValue;
- }
- public AtomicReference() {
- }
- public final V get() {
- return value;
- }
- public final void set(V newValue) {
- value = newValue;
- }
- public final void lazySet(V newValue) {
- unsafe.putOrderedObject(this, valueOffset, newValue);
- }
- public final boolean compareAndSet(V expect, V update) {
- return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
- }
- public final boolean weakCompareAndSet(V expect, V update) {
- return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
- }
- public final V getAndSet(V newValue) {
- while (true) {
- V x = get();
- if (compareAndSet(x, newValue))
- return x;
- }
- }
- public String toString() {
- return String.valueOf(get());
- }
- }<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示例
- // AtomicReferenceTest.java的源码
- import java.util.concurrent.atomic.AtomicReference;
- public class AtomicReferenceTest {
- public static void main(String[] args){
- // 创建两个Person对象,它们的id分别是101和102。
- Person p1 = new Person(101);
- Person p2 = new Person(102);
- // 新建AtomicReference对象,初始化它的值为p1对象
- AtomicReference ar = new AtomicReference(p1);
- // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。
- ar.compareAndSet(p1, p2);
- Person p3 = (Person)ar.get();
- System.out.println("p3 is "+p3);
- System.out.println("p3.equals(p1)="+p3.equals(p1));
- }
- }
- class Person {
- volatile long id;
- public Person(long id) {
- this.id = id;
- }
- public String toString() {
- return "id:"+id;
- }
- }<span style="font-family: 'Courier New' !important; font-size: 12px !important; line-height: 1.5 !important; color: rgb(0, 0, 0);"></span>
运行结果:
- p3 is id:102
- 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相关推荐
- Java多线程系列--“JUC原子类”01之 框架
2019独角兽企业重金招聘Python工程师标准>>> Java多线程系列--"JUC原子类"01之 框架 根据修改的数据类型,可以将JUC包中的原子操作类可以分 ...
- Java多线程知识小抄集(二)
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- Java 多线程 并发编程
转载自 Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...
- 40个问题让你快速掌握Java多线程的精髓
本文分享自华为云社区<对Java多线程的用法感到一头乱麻?40个问题让你快速掌握多线程的精髓>,原文作者:breakDraw . 多线程可以理解为在同一个程序中能够同时运行多个不同的线程来 ...
- 万字图解Java多线程,不信你学不会!
来源:Java面试题精选 前言 java多线程我个人觉得是javaSe中最难的一部分,我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程a ...
- java多线程学习笔记。
java多线程学习笔记 线程的优缺点: 多线程的好处: 充分利用多处理核心,提高资源的利用率和吞吐量. 提高接口的响应效率,异步系统工作. 线程的风险: 安全危险(竞争条件):什么坏事都没有发生.在没 ...
- Java多线程--概述-转自Kyrie lrving
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- java多线程高级:JUC
文章目录 java多线程高级:JUC 1 多线程锁 1.1 传统synchronized 1.2 Lock接口 1.3 Synchronized和Lock的区别 2生产者和消费者问题 2.1 Sync ...
- 2021全新Java多线程并发入门到精通,一篇就能学会
目录 一, JAVA 多线程并发 1,JAVA 并发知识库 2,JAVA 线程实现/创建方式 (1) 继承 Thread 类 (2)实现 Runnable 接口. (3)ExecutorService ...
最新文章
- 购买过php,【已解决】PHP项目需求:用户购买商品时,给上级发送一条通知(无限级下级会员)...
- 安装php报错误2356,linux下Mysql+php5+apache安装手记
- property的修饰符
- jms spring_JMS和Spring:有时很重要的小事情
- webjs求数组的中位数‘_算法:一道常见的数组题,但很多人却写不出来(JAVA)...
- Bootstrap HTML 编码规范之布尔型属性
- Python: subprocess.Popen()不支持unicode问题解决
- spyder里import tensorflow报错显示没有tensorflow模块解决
- Tensorflow2.0实战之Auto-Encoder
- gotoxy函数定义
- 最强半自动化抓鸡工具打造思路
- java 传智播客 毕向东_传智播客:毕向东Java基础视频教程(全5)压缩包电驴下载...
- Mac墨刀怎么导出HTML,mockingbot墨刀中文使用说明.pdf
- web大作业介绍自己的家乡_中国10大乡村名鸭!快来看看自己家乡的鸭子是否上榜...
- 漂亮的表格样式(使用CSS样式表控制表格样式)
- logstash的lumberjack协议解析
- c++数独游戏3.3
- CSS基础(11)- 浮动
- h5 html页面百度定位当前位置不准
- FS78P372N单片机替代义隆EM78P372N
热门文章
- VMware中为linux设置网络
- Git常用的基本命令
- 7-19晚牛客网刷题未知点、错题 集合
- ios查看ipa是否函数特定字符_iOS 中基础字符判断函数收集(如判断大小写、数字等)...
- r语言plot函数x轴y轴名字_Matplotlib入门-1-plt.plot( )绘制折线图
- 神策 2021 数据驱动大会,科特勒、桑文锋等发出营销未来之强音
- 神策数据王琛:用户画像实践之神策标签生产引擎架构
- 百果园付凌峰:线上单月 1.2 亿背后的数据化运营
- 有一天老板和我要几个关键数据……
- Ubuntu 修改mysql存放路径后无法启动解决办法