原文地址: http://coderbee.net/index.php/java/20131117/581
volatile 变量
volatile变量具有可见性,也就是说线程能够自动发现volatile 变量的最新值;对volatile变量进行操作不会造成阻塞。
适用于:多个变量之间或者某个变量的当前值与修改后值之间没有约束。
正确使用volatile变量的条件:
- 对变量的写操作不依赖于当前值。
- 该变量没有包含在具有其他变量的不变式中。
所以,volatile变量不支持像i++
这样的原子操作,因为这条语句包含了三个步骤:读取-加1操作-写变量。
CAS操作
大多数CPU都提供了CAS操作指令,这条指令的作用是:对于一个变量var,如果它的当前值是excepted,则把它的值更新为newValue,否则就不更新。
由于JVM屏蔽了操作系统有关的细节,HotSpot虚拟机通过sun.misc.Unsafe
类提供了这样的操作指令。
原子类
原子类是对volatile变量的增强,提供了一些稍微复杂的符合操作,如上面提到的i++
操作。这里以java.util.concurrent.atomic.AtomicInteger
为例。
直接读写操作
AtomicInteger有一个volatile int value
属性表示对象的值,这样,对变量的读写操作就可以借助volatile语义直接完成。
public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}
CAS操作
compareAndSet是通过unsafe类的本地方法来实现的,这个方法也是实现其他复合操作的方法的基础。
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
对变量的加减操作
CPU虽然提供了CAS这样的操作指令,但并没有提供类似这样的操作:对变量加一个指定的值,再返回旧值。但AtomicInteger类却能够提供,下面就看看里面的魔法:
public final int getAndAdd(int delta) {
for (;;) {
int current = get(); //step 1
int next = current + delta; //step 2
if (compareAndSet(current, next)) //step 3
return current;
}
}
这个方法很简洁,在一个无穷的循环里面不断尝试这样的操作序列:先取变量的当前值,进行加操作,然后用CAS操作设置新的值,如果设置成功则返回,否则继续尝试。
这里之所以要放到一个无穷循环里进行操作,是因为step 1之后,step 3成功之前,变量的值都有可能被改变,只要变量的值被其他线程修改了,就需要重试。但只要线程之间的写竞争不激烈,这个操作序列就总会成功。
总的来说,原子类的复合操作的实现思路是:CAS + 失败后不断重试。
其他的类似操作也是采用这样的思路实现的。
ABA问题
在上面的getAndAdd
方法的实现里,线程T执行step1后、执行step3之前被挂起,另一个线程T2把value
属性从A修改为B,然后又修改回A,那么T恢复执行时,它是不会发现value
曾经被修改,继续执行step 3是成功的。这个问题就是ABA问题。
ABA问题的解决思路是给变量的值关联一个戳记,每次修改变量的值时同时改变戳记,那么即使变量的值不变也可以发现它是否被修改过。
AtomicBoolean
这里要特别说下的是AtomicBoolean的实现。boolean只能表示true或false,只需要一个比特位就够了,但所有CPU都不直接读写某个比特位,最小的也是字节。
相关推荐
Java 多线程与并发(8_26)-JUC原子类_ CAS, Unsafe和原子类详解
主要介绍了java JUC原子类基本类型详解的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
主要介绍了JAVA JUC原子类 数组类型详解的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
原子类 java.util.concurrent.atomic包:原子类的小工具包,支持在单个变量上解除锁的线程安全编程 原子变量类相当于一种泛化的 volatile 变量,能够支持原子的和有条件的读-改-写操作。AtomicInteger 表示一个int...
尚硅谷_JUC线程高级_原子变量与 CAS 算法 ·3. 尚硅谷_JUC线程高级_模拟 CAS 算法 ·4. 尚硅谷_JUC线程高级_同步容器类ConcurrentHashMap ·5. 尚硅谷_JUC线程高级_CountDownLatch 闭锁 ·6. 实现 Callable 接口 ·...
原子操作:JUC提供了一些原子操作类,如AtomicInteger、AtomicLong等,可以实现线程安全的原子操作,避免了使用synchronized关键字的性能损耗。 锁机制:JUC提供了Lock接口和Condition接口,可以实现更细粒度的锁...
原子操作是不可再分割的基本操作,JUC 提供了一系列原子操作类,如 AtomicInteger、AtomicLong 等。 4. 同步器(Synchronizers):JUC 中的同步器主要通过 AQS(AbstractQueuedSynchronizer)提供支持。
Java并发工具包实例,包含AQS,LOCK,countdownlatch ,atomic原子类等实例
一、理论基础 1.1为什么需要多线程 1.2不安全示例 1.3并发问题的根源 1.4JMM 1.5线程安全的分类 1.6线程安全的方法 二、线程基础 ...十、原子类-CAS, Unsafe和原子类详解 十一、JUC锁: LockSupport详解
主要介绍了Java多线程Atomic包操作原子变量与原子类详解,简单介绍了Atomic,同时涉及java.util.concurrent中的原子变量,Atomic类的作用等相关内容,具有一定参考价值,需要的朋友可以了解下。
上半场,从多线程并发入手,分层递进讲解,逐步让大家掌握volatile、原子类和原子引用、CAS、ABA、Java锁机制、阻塞队列、线程池等重点;下半场,逐步过渡到JVM和GC的知识,深度讲解多种常见OOM异常和JVM参数调优,...
上半场,从多线程并发入手,分层递进讲解,逐步让大家掌握volatile、原子类和原子引用、CAS、ABA、Java锁机制、阻塞队列、线程池等重点;下半场,逐步过渡到JVM和GC的知识,深度讲解多种常见OOM异常和JVM参数调优,...
我们经常在JUC包下的ConcurrentHashMap、Atomic开头的原子操作类、AQS以及LockSupport里面看到Unsafe类的身影,这个Unsafe类究竟是干什么的,本文可以带着读者一探究竟。 Java和C++、C语言的一个重要区别,就是Java...
java.util.concurrent ,包 对应JUC并发编程 笔记和JUC-API 还有 Java原子类 CAS
资源概要:1,多线程;2,synchronized;3,volatile;4,多线程在JVM中的实现...原子类Atomic-CAS及其实现原理 锁Lock-AQS核心原理剖析 并发工具类、并发容器、阻塞队列 线程池原理剖析 线程池案例-Web容器-压力测试
上半场,从多线程并发入手,分层递进讲解,逐步让大家掌握volatile、原子类和原子引用、CAS、ABA、Java锁机制、阻塞队列、线程池等重点;下半场,逐步过渡到JVM和GC的知识,深度讲解多种常见OOM异常和JVM参数调优,...
上半场,从多线程并发入手,分层递进讲解,逐步让大家掌握volatile、原子类和原子引用、CAS、ABA、Java锁机制、阻塞队列、线程池等重点;下半场,逐步过渡到JVM和GC的知识,深度讲解多种常见OOM异常和JVM参数调优,...
原子性 有序性 哪些地方用到过volatile? 单例模式的安全问题 CAS CAS底层原理 CAS缺点 ABA问题 AtomicReference AtomicStampedReference和ABA问题的解决 集合类不安全问题 List CopyOnWriteArrayList Set HashSet和...
课程内容包括了JAVA手写线程池,UC线程池API详解,线程安全根因详解,锁与原子类,分布式锁原理与实现方式,并发编程-AQS等等针对性非常强的JAVA编程开发教程,这其中的内容对JAVA开发技能的拔尖,非常的有帮助。...