-
JMM介绍:
java内存模型是一种抽象的概念,并不真实存在。规定变量都存储在主内存中,主内存是共享区域,所有的线程都可以访问。但对变量的操作必须在工作内存完成(工作内存是JVM为每个线程创建的私有数据区域),首先将变量从主内存拷贝到自己的工作内存,然后对变量进行操作,操作完成写回主内存。
-
三个特性:
1.可见性:
多个线程操作共享数据彼此可见
;
2.原子性:操作是连续不可分割
;
3.有序性:计算机执行程序为了提高性能,编译器和处理器常常会对指令重排,分三种:1、编译器优化的重排;2、指令并行的重排;3、内存系统的重排,它们需要数据的依赖性来保证最终结果一致,可以禁止指令重排
;
Volatile
是一种轻量级的锁,可以保证内存可见性和有序性(禁止指令重排),不保证原子性。使用场景如:本地程序缓存同步,判断是否正在同步的标志可以使用volatile修饰。
AtomicInteger或AtomicReference
可以实现原子性,底层采用的CAS算法。算法思路有三个值:1、内存值;2、预估值;3、更新值;只有内存值等于预估值时,才会把更新值赋值给内存值,否则自旋。
CAS全称Compare And Swap,是一条CPU并发原语句,执行过程中不允许被中断。
CAS核心类时UnSafe类,该类所有的方法都是native修饰,可以直接操作特定的内存数据。
CAS缺点:循环时间长开销会很大;只能保证一个共享变量的原子操作;存在ABA问题。ABA问题比如:线程一从内存位置V取出值A,线程二也从内存位置V取出值A,并修改为B,再改为A。此时线程一发现内存中仍然是A,然后操作成功,但这个过程是有问题的。
解决ABA问题,引入版本号机制,可以使用AtomicStampReference.