AtomicReference 原子引用】的更多相关文章

AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,底层采用的是compareAndSwapInt实现CAS,比较的是数值是否相等,而AtomicReference则对应普通的对象引用,底层使用的是compareAndSwapObject实现CAS,比较的是两个对象的地址是否相等.也就是它可以保证你在修改对象引用时的线程安全性. 顺便说一下:引用类型的赋值是原子的.虽然虚拟机规范中说64位操作可以不是原子性的,可以分为两个3…
1.CAS导致ABA问题: CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并交换,那么在这个时间差中会导致数据的变化. 比如:线程1从内存位置V中取出A,这时线程2也从V中取出A,线程2进行了一些操作将值改成了B,然后线程2又将V的数据改回A:此时线程1进行CAS操作发现内存中仍然是A,然后线程1操作成功. 尽管线程1的CAS操作成功,但是不代表这个过程就是没有问题的. 解决ABA问题:利用原子引用+修改版本号(类似时间戳),每次需要获取到版本最新的值进行处理. 2.原子引…
我们知道在并发编程中,多个线程共享某个变量或者对象时,必须要进行同步.同步的包含两层作用:1)互斥访问(原子性):2)可见性:也就是多个线程对共享的变量互斥地访问,同时线程对共享变量的修改必须对其他线程可见,也就是所有线程访问到的都是最新的值. 1. volatile变量和volatile引用 volatile的作用是:保证可见性,但是没有互斥访问语义(原子性语义).volatile能够保证它修饰的引用以及引用的对象的可见性,volatile不仅保证变量或者引用对所有访问它的线程的可见性,同时能…
/** * NumberRange * <p/> * Number range class that does not sufficiently protect its invariants * * @author Brian Goetz and Tim Peierls */ public class NumberRange { // INVARIANT: lower <= upper private final AtomicInteger lower = new AtomicInteg…
前言 相信大部分开发人员,或多或少都看过或写过并发编程的代码.并发关键字除了Synchronized,还有另一大分支Atomic.如果大家没听过没用过先看基础篇,如果听过用过,请滑至底部看进阶篇,深入源码分析. 提出问题:int线程安全吗? 看过Synchronized相关文章的小伙伴应该知道其是不安全的,再次用代码应验下其不安全性: public class testInt { static int number = 0; public static void main(String[] ar…
本篇看一下Volatile关键字和原子引用. 上图就是JUC包结构,总共分成三块 (1)java.util.concurrent:并发包基础类,包括阻塞队列,线程池相关类,线程安全Map等. (2)java.util.concurrent.atomic:原子引用相关类 (3)java.util.concurrent.locks:线程锁相关类 线程池技术在之前的讲解应该很清楚了,今天主要解析一个volatile关键字以及原子引用的相关类.这一篇文件涉及到JMM(java内存模型)的知识,之前也有讲…
18彻底玩转 单例模式 饿汉式 DCL懒汉模式 探究! 饿汉式  package com.kuang.single; //饿汉式单例 //单例模式重要思想是构造器私有 public class Hungry { ​     //可能会浪费空间     private byte[] data1 = new byte[1024*1024];     private byte[] data2 = new byte[1024*1024];     private byte[] data3 = new b…
1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁.JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁. 2.CAS算法理解 对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B.当且仅当预期值A和内存值V相同时,将内存值V修改为B,…
当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线程改过了.什么是线程安全呢?用并发编程实战里面的一段话解释说: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的 这里需要注意的是多个线程,如果一个线程肯定是线程安全的,而且这里的共…
1.什么是CAS CAS 即 compare and swap 比较并交换, 涉及到三个参数,内存值V, 预期值A, 要更新为的值B, 拿着预期值A与内存值V比较,相等则符合预期,将内存值V更新为B, 不相等,则不能更新V. 为什么预期值A与内存值V不一样了呢? 在多线程环境下,对于临界区的共享资源,所有线程都可以访问修改,这时为了保证数据不会发生错误,通常会对访问临界区资源加锁,同一时刻最多只能让一个线程访问(独占模式下),这样会让线程到临界区时串行执行,加锁操作可能会导致并发性能降低,而循环…
本期内容包括 JUC多线程并发.JVM和GC等目前大厂笔试中会考.面试中会问.工作中会用的高频难点知识.斩offer.拿高薪.跳槽神器,对标阿里P6的<尚硅谷_互联网大厂高频重点面试题(第2季)>发布.本套课程总结分析了2019年大厂互联网公司常见常考的技术点,通过对40多个题目共计120集视频详细全面的讲解,让大家深刻掌握.扎实吃透当前的主流Java高级技术. NoSQL数据库Redis 消息中间件MQ JUC多线程及高并发并发和并行有什么区别并发:多个线程去访问同一个资源并行:各种事情同时…
CAS是什么? 比较并交换 例子1: public class ABADemo1 { public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(5); System.out.println(atomicInteger.compareAndSet(5,2019)+"\t当前值是:"+atomicInteger.get()); System.out.println(ato…
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯哥(凯哥Java:kagejava)并发编程学习>系列之<CAS系列>教程的第三篇:CAS的缺点有哪些?怎么解决. CAS的缺点 一:do while循环时间长的话开销大 从源码中(见上图),我们可以知道do while中的while返回true会一直循环下去(具体分析步骤见上一篇:<…
CAS是什么? 比较并交换. CAS示例 package com.chinda.java.audition; import java.util.concurrent.atomic.AtomicInteger; /** * CAS示例 * 1. 什么是CAS * CAS就是比较并交换 * * @author Wang Chinda * @date 2020/5/3 * @see * @since 1.0 */ public class CASDemo { static AtomicInteger…
Linus大神又在rant了!这次的吐槽对象是时下很火热的并行技术(parellism),并直截了当地表示并行计算是浪费所有人时间(“The whole “let’s parallelize” thing is a huge waste of everybody’s time.”).大致意思是说乱序性能快.提高缓存容量.降功耗.当然笔者不打算正面讨论并行的是是非非(过于宏伟的主题),因为Linus在另一则帖子中举了对象引用计数(reference counting)的例子来说明并行的复杂性. 在…
众所周知,java1.5并发包通过volatile+CAS原理提供了优雅的并发支持.今天仔细想想.net也有volatile关键字保证内存的可见性,同时也有Interlocked提供了CAS的API,因此突发奇想--对着java并发包写一下.net并发包.第一步就是原子类型的实现(.NET目前还没有原子类型) 项目地址:https://github.com/FanHuaRan/Dotnet.Concurrent 一.原子int /// <summary> /// 原子int 基于CAS+自旋无…
AtomicReferenceFieldUpdater是基于反射的工具类,用来将指定类型的指定的volatile引用字段进行原子更新,对应的原子引用字段不能是private的.通常一个类volatile成员属性获取值.设定为某个值两个操作时非原子的,若想将其变为原子的,则可通过AtomicReferenceFieldUpdater来实现.如下面例子: public class AtomicReferTest { public static void main(String[] args) thr…
1.前言 struct kref结构体是一个引用计数器,它被嵌套进其它的结构体中,记录所嵌套结构的引用计数.引用计数用于检测内核中有多少地方使用了某个对象,每当内核的一个部分需要某个对象所包含的信息时,则该对象的引用计数加1,如果不需要相应的信息,则对该对象的引用计数减1,当引用计数为0时,内核知道不再需要该对象,将从内存中释放该对象. 2.kref结构体 在Linux的内核源码中,struct kref结构体的定义在include/linux/kref.h文件中,结构体定义如下所示: stru…
非阻塞的同步机制 简单的说,那就是又要实现同步,又不使用锁. 与基于锁的方案相比,非阻塞算法的实现要麻烦的多,但是它的可伸缩性和活跃性上拥有巨大的优势. 实现非阻塞算法的常见方法就是使用volatile语义和原子变量. 硬件对并发的支持 原子变量的产生主要是处理器的支持,最重要的是大多数处理器架构都支持的CAS(比较并交换)指令. 模拟实现AtomicInteger的++操作 首先我们模拟处理器的CAS语法,之所以说模拟,是因为CAS在处理器中是原子操作直接支持的.不需要加锁. public s…
目录 1,基本概念 2,volatile 3,atom 4,ThreadLocal 5,CountDownLatch和CyclicBarrier 6,信号量 7,Condition 8,Exchanger 在Java中,JVM.并发.容器.IO/NIO是我认为最重要的知识点,本章将介绍其中的并发,这也是从“会Java”到精通Java所必须经历的一步.本章承接上一张<Java系列笔记(5) - 线程>,其中介绍了Java线程的相关知识,是本章介绍内容的基础,如果对于线程不熟悉的,可以先阅读以下这…
我们知道Java语言中没有指针,取而代之的是引用reference.Java中的引用又可以分为四种:强引用,弱引用(WeakReference),软引用(SoftReference),虚引用(PhantomReference).其中强引用,就是我们平时使用的最多的最普通的引用,虚引用一般我们是没有机会使用到的.所以我们主要了解下 WeakReference 和 SoftReference(除了上面说的四种引用之外,其实还有一种引用——原子引用AtomicReference,用于并发编程环境).…
背景 最近在啃<多处理器编程的艺术>,书中的7.6节介绍了时限锁--实现了tryLock方法的队列锁. 书中重点讲解了tryLock的实现,也就是如何实现在等待超时后退出队列,放弃锁请求,并且能让后继线程感知到. 在实现的过程中,我为TOLock补充了lock方法的实现.代码如下所示: public class TOLock implements Lock { private static final QNode AVAILABLE = new QNode(); private AtomicR…
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更新变量I的时候拿到的 I都是1,,这就是线程不安全的更新操作,通常我们会使用synchronized来解决这个问题,synchronized会保证多线程不会同时更新变量 I. 而java从jdk1.5开始提供了javalutil.concurrent.atomic包(简称Atomic包),这个包中的…
CAS(Compare-and-Swap),即比较并替换,java并发包中许多Atomic的类的底层原理都是CAS. 它的功能是判断内存中某个地址的值是否为预期值,如果是就改变成新值,整个过程具有原子性. 具体体现于sun.misc.Unsafe类中的native方法,调用这些native方法,JVM会帮我们实现汇编指令,这些指令是CPU的原子指令,因此具有原子性. public class CASDemo { public static void main(String[] args) { /…
第一章:简介 程序清单1-1非线程安全的数值序列生成器 import net.jcip.annotations.NotThreadSafe; @NotThreadSafe public class UnsafeSequence { private int value; /*返回一个唯一的数值*/ public int getValue() { return value++; //三个操作:读取,加一,赋值. 多线程并发操作value可能导致步骤被打乱 } } 程序清单1-2 线程安全的数值序列生…
面试时被问到了,补下 import java.util.concurrent.atomic.AtomicInteger; /** * Created by tzq on 2018/7/15. */ public class TestAtomic { /** * @param java中的原子操作类AtomicInteger * @author yangcq * * 关于AtomicInteger的说明(来自官方文档注解) * /** * An {@code int} value that may…
在多线程环境下,如果某个类是有状态的,那我们在使用前,需要保证所有该类的实例对象状态一致,否则会出现意向不到的bug.下面是通用线程安全状态机的实现方法. public class ThreadSaveState{ private int x; private int y; private enum State {NEW, INITIALIZING, INITIALIZED}; private final AtomicReference<State> init = new AtomicRefe…
1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(bool on):true则把该线程设置为守护线程,反之则为用户线程.Thread.setDaemon()必须在Thread.start()之前调用,否则运行时会抛出异常. 两者的区别: 唯一的区别是判断虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部的User Thread已经…
要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享(Shared)和可变的(Mutable)状态的访问. “共享”意味着变量可以由多个线程同时访问,而“可变”则意味着变量的值在其生命周期内可以发生变化.我们将像讨论代码那样来讨论线程安全性,但更侧重于如何防止数据在数据上发生不可控的并发访问. 当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变量的访问.Java 中的主要同步机制是关键字 synchronized ,它提供了一种独占的…
1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(bool on):true则把该线程设置为守护线程,反之则为用户线程.Thread.setDaemon()必须在Thread.start()之前调用,否则运行时会抛出异常. 两者的区别: 唯一的区别是判断虚拟机(JVM)何时离开,Daemon是为其他线程提供服务,如果全部的User Thread已经…