22 volatile原理分析
2020-07-18 本文已影响0人
滔滔逐浪
什么是volatile
volatile 是java 提供的轻量级的同步机制,保证了可见性,不保证原子性。
java语言包含2种内在的同步机制: 同步块(或方法)和volatile变量, 相比于synchronized(synchronize 通常称为重量级锁),volatile更轻量级,因为他
能够保证线程可见性,当一个线程修改共享变量的时候,能够对另外一个线程可见性。但是注意他不能保证共享变量的原子性问题。
volatile的特性:
能够保证线程的可见性,当一个线程修改共享变量时,能够保证对另外一个线程可见性,但是注意他不能保证共享变量的原子性问题。
顺序性:
程序员执行程序按照代码的先后顺序执行:
原子性:
即一个或者多个操作要么全部成功,要么全部失败。
volatile可见性:
package com.taotao.zuoye.thread;
/**
*@author tom
*Date 2020/7/18 0018 9:12
*volatitle 可见性
*/
public class Mayikt extends Thread {
private static volatile boolean Flag=true;
@Override
public void run() {
while (Flag){
System.out.println("执行");
}
}
public static void main(String[] args) throws InterruptedException {
new Mayikt().start();
Thread.sleep(1000);
Flag=false;
}
}
```’
jmm内存模型:
java 内存模型定义的是一种抽象的概念,定义屏蔽java程序对不同的操作系统的内存访问差异
主内存:
存放我们共享变量的数据
工作内存:
每个cpu对共享变量(主内存)的副本;
总线: 维护解决cpu高速缓存副本数据之间一致性问题:
1,E 独享状态: 在单核的情况下,只有一个线程 当前线程工作内存(主内存副本数据)与主内存数据保持一致性的则 当前cpu状态:E独享状态;
2,S 表示为共享 在多个cpu 的情况下 每个线程中工作内存中(主内存中副本数据)与主内存数据保持一致
则当前cpu的状态为:S 共享状态
3, M 修改 当前线程修改了工作内存中的数据,当前cpu的副本数据与主内存的数据不一致的情况下,则淳朴的状态为 M 状态
4, I 无效 总线程嗅探机制,如果发现cpu 中副本数据与主内存数据不一致的情况下,则会认为无效要从新刷新主内存的数据到工作内存中。
为什么 volatile 不能保证原子性
2个子线程同时修改变量,这时一个子线程的变量的值同步到主内存,通过emsi机制,主内存的值就同步到另外个线程,所以出现原子性问题。
synchronized 线程解锁前 必须把共享变量的最新值刷新到主内存中;
线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量是需要从主内存中重新读取最新的值