对于原子类变量的操作是不会存在并发性问题的,不需要使用synchronized关键字额外的实现线程同步。它底层自身的实现即可保证变量的可见性以及操作的原子性。一般我们可以使用AtomicInteger,AtomicLong等实现计数器等功能,利用AtomicBoolean实现标志位等功能。
实现线程安全的常见两种机制:
- 加锁机制(常见synchronized和ReentrantLock等),特点:阻塞
- 无锁机制(常见无锁算法有:CAS算法),特点:非阻塞
原子量底层的实现均是采用CAS非阻塞算法实现的,是无锁(lock-free)算法中最有名的一种(无锁算法:不使用锁机制来实现线程安全的算法,采用锁机制都会存在线程为请求锁而产生阻塞的情况),CAS不会阻塞线程从而不会带来CPU上下文切换的性能开销。
CAS非阻塞算法的思想:
CAS的全称是Compare-And-Swap(意思是比较后交换):指当两者(这个两者是指线程栈内存中备份的共享变量值和主内存中共享变量值)进行比较时,如果值相等,则证明共享数据没有被其他线程修改过,替换成新值,然后继续往下运行;如果不相等,说明主内存中的共享数据被其它线程修改过,放弃已经所做的操作,然后重新执行刚才的操作(可见CAS算法的关键就是这个循环体结构,退出循环的条件是主内存中的共享数据没有被其他线程修改过,如果被修改过,则该线程会重复执行此操作,直到满足退出循环体的条件为止,这也是为什么线程不会阻塞的原因)。容易看出 CAS 操作是基于共享数据不会被修改的假设,采用了类似于数据库的 commit-retry 的模式。当同步冲突出现的机会很少时,这种假设能带来较大的性能提升。
下面以AtomicInteger类的具体实现为例,进一步还原CAS算法使用的真相:
public class AtomicInteger extends Number implements java.io.Serializable { private static final longserialVersionUID = 6214790243416807050L; // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final longvalueOffset;//value字段相对AtomicInteger对象内存地址的偏移量
static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { thrownew Error(ex); } }
private volatile int value;//该AtomicInteger原子量对应的值value(共享变量)
//该方法的作用value++的线程安全版,返回自增长以前的值 public final int getAndIncrement() { for (;;) {//CAS算法中循环体结构 int current = get();//获取并备份主内存共享变量值 int next = current + 1; if (compareAndSet(current, next))//主内存变量更新成功,则退出循环体,否则重复执行此自增操作,直到更新成功为止。 return current;//返回自增长以前的值 } } //拿expect和主内存中的值进行比较,如果相等,说明主内存中的值没有发生过修改 //则将新值写入到主内存,return true。否则直接return false; public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } |
相关推荐
Java Atomic原子类的使用方法和原理 Java Atomic原子类是Java中的一种多线程安全机制,用于在多线程环境中保证变量的原子性操作。Atomic原子类的出现解决了多线程环境下变量操作的安全问题,使得开发者可以更方便地...
本文将深入探讨Java开发中的原子操作实现原理,以及如何利用这些知识来优化Java应用。 首先,我们需要理解什么是原子操作。原子操作是指不可分割的操作,它要么全部完成,要么完全不执行,中间不会被其他线程中断。...
#### 三、Java原子类实现原理 - Java的原子类,如 `AtomicInteger`,使用了 CAS (Compare and Swap) 指令来实现原子操作。 - CAS 操作依赖于底层硬件的支持,通过 CPU 提供的原语指令来保证原子性。 - 原子类内部...
4. 原子类的工作原理: 原子类内部利用了Java内存模型中的CAS(Compare and Swap,比较并交换)操作来保证线程安全。CAS操作会检查指定的内存位置的值是否与期望值相等,如果相等则更新该位置的值,否则不做任何...
本篇文章将深入分析Volatile的实现原理,结合`LinkedTransferQueue`和`TransferQueue`这两个与并发相关的Java源码,探讨其在多线程环境中的应用。 首先,我们需要理解Java内存模型(JMM,Java Memory Model),它是...
Java原子变量类原理及实例解析 一、原子变量类简介 Java中的原子变量类是为了解决多线程环境下数据的一致性问题而设计的。它可以确保多线程环境下数据的原子性、可见性和有序性。原子变量类的主要特点是它可以在多...
阻塞队列、原子操作的原理分析1】 在Java编程中,阻塞队列(Blocking Queue)是一种线程安全的数据结构,它在多线程环境中扮演着重要的角色,特别是在并发处理和解耦组件之间通信时。阻塞队列的核心特性在于它能够...
通过理解CAS的工作原理和底层实现,我们可以更有效地使用Java中的原子类和无锁数据结构。然而,我们也需要意识到CAS操作的局限性,并在实际应用中采取相应的策略来解决这些问题。通过合理使用CAS操作,我们可以编写...
在Java中,`java.util.concurrent.atomic`包下的原子类,如`AtomicInteger`,就是基于CAS实现的。 以`AtomicInteger`的`incrementAndGet()`方法为例,它用于实现无锁的自增操作。在循环中,线程首先获取当前值,...
下面我们将深入探讨`AtomicLongArray`的基本概念、常用方法以及其实现原理。 `AtomicLongArray`是Java并发库提供的一个原子性操作长整型数组的类,它支持线程安全的增加、减少、比较并设置、获取和设置等操作,而...
在本研究中,陈晓劼、吴其胜、陈乾和王金兰利用第一性原理计算方法,对Ag原子修饰石墨烯和氮化硼(BN)薄膜的二维纳米材料进行了理论研究。研究发现,Ag原子的表面修饰能够显著改变这些材料的性质,具体表现为石墨烯...
本篇将深入解析Hive的实现原理,特别是如何在Hive中更新数据。 首先,我们来了解Hive的核心概念。Hive是一个基于Hadoop的数据仓库工具,它将结构化的数据文件映射为一张数据库表,并提供SQL查询功能。Hive的查询...
通过对原子操作和 일반操作的比较,了解为什么需要使用原子类,如何使用AtomicLong和其他原子类来实现线程安全的编程。 一、原子操作与一般操作的异同 在Java中,当我们对一个普通变量进行操作时,Java编译器会将...
JDK5提供的原子类的操作以及实现原理.mp4 Lock接口认识与使用.mp4 手动实现一个可重入锁.mp4 AbstractQueuedSynchronizer(AQS)详解.mp4 使用AQS重写自己的锁.mp4 重入锁原理与演示.mp4 读写锁认识与原理.mp4 细读...
在Java的并发编程中,AtomicInteger 是一个非常重要的原子类,它提供了一种无锁的机制来保证整数操作的原子性。本文将详细介绍 AtomicInteger 的工作原理、使用方法以及如何在实际项目中应用它。 AtomicInteger 是...
《C语言与实现测试》是一本深入探讨C语言底层机制的书籍,旨在帮助读者理解C语言的实现原理和测试方法。在这个压缩包“C语言与实现测试-原子.zip”中,我们可以找到一系列与原子操作相关的实验程序。原子操作在多...
3. 轨道离子阱的工作原理类似电子绕原子核旋转,离子在中心纺锤形电极周围做旋进运动。不同质量的离子在达到共振时速度不同,通过检测这些离子通过检测器的时间顺序,可以得到高分辨率的质谱图。然而,轨道离子阱对...
Java原子操作CAS原理解析 Java原子操作CAS原理解析是Java并发编程中的一种机制,用于解决多线程并行情况下使用锁造成的性能损耗。CAS操作包含三个操作数——内存位置(V)、预期原值(A)、新值(B)。如果内存位置的...