Java 之 volatile是什么?

1.JUC:java并发包java.util.concurrent
2.volatile:java虚拟机提供的轻量级同步机制,特性:保证可见性,不保证原子性,禁止指令重排。

**工作内存和主内存之间同步延迟导致的可见性问题,可以使用synchronized或volatile关键字解决,它们都可以使一个线程修改后的变量立即对其他变量可见。
**对于指令重排导致的可见性和有序性问题,可以使用volatile关键字解决,因为volatile的另一个作用是禁止指令重排优化

2.1.可见性:volatile修饰的变量,一旦在某一线程中改变,就会将最新值同步至主内存及其他所有工作内存
2.2.不保证原子性:
2.2.1:原子性指什么?原子性指不可分割,具有完整性。当某一线程在做一个业务时,具有完整性,要么同时成功,要么同时失败,中间不可以被加塞或分割。这种就叫做具有原子性。
2.2.2:如何解决原子性(eg.多线程i++)?a.用sync修饰变量;b.使用带原子性的包装类型;
2.3.禁止指令重排:
2.3.1.指令重排:源代码->编译器优化的重排->指令并行的重排->内存系统的重排->最终执行的命令;
(*编译器指令重排时会考虑数据依赖性,即不是任意重排)
(*指令重排只会保证单线程的一致性,并不会关心多线程间的语义一致性)
多线程环境中线程交替执行,由于编译器优化重排机制,多个线程中使用的变量能否保证一致性无法确定,结果无法预测。如下
Java 之 volatile是什么?_第1张图片
2.3.2.volatile通过内存屏障禁止指令重排
Java 之 volatile是什么?_第2张图片
3.JMM:java内存模型是一种抽象的概念,描述的是一组规则或一种规范,通过JMM定义了程序中各个变量(实例字段,静态字段,构成数组对象的元素)的访问方式
3.1.JMM关于同步的规定
a.线程解锁前,必须把共享对象的值刷新回主内存;
b.线程加锁前,必须将主内存中的最新值放到自己的工作内存;
c.加锁解锁是同一把锁
JVM:java虚拟机。
JMM:java内存模型。
主内存:所有变量都可以访问的共享内存区域,所有变量都存在主内存中。
工作内存:每个线程对应的私有内存区域,线程只能对自己的私有内存区域进行操作,不能直接操作主内存,其操作方式是:先将主内存变量备份至工作内存中,操作完成后再同步至主内存。各个线程之间无法直接相互访问,他们之间的通信必须通过主内存。
Java 之 volatile是什么?_第3张图片
DCL(double check lock双端检锁机制)(不一定线程安全)
在synchronized锁前后加入if(instance==null)判断,防止变量同步延迟等可见性问题,但是无法防止由于指令重排引起的问题。

你可能感兴趣的:(java,java,锁)