请描述volatile关键字的作用及使用场景,volatile关键字的应用场景
原子性,并发编程中的三个概念,其实在数据库中也有体现。以转学为例。张三转账一块钱给李四,业务逻辑是张三减一块钱,李四加一块钱。这些必须同时成功。此处省略一万字。
可视性操作系统在CPU访问数据时其实是有多级缓存的,如下图所示(深刻理解计算机系统原书第三版)。当多个CPU访问一个数据时,会先将主存中的数据缓存到缓存中,然后再执行操作。所以如果两个CPU同时执行a=a 1操作,如果没有一定的同步方法,那么就会出现修改丢失的问题,所以可见性就是保证一个CPU会是一个CPU。
根据JMM的说法,Java内存模型规定所有变量都存储在主存中,每个线程都有自己的工作内存。一个线程的工作内存保存着该线程使用的变量的主存副本,一个线程对变量的所有操作都必须在工作内存中进行,而不是直接读写主存。不同的线程不能直接访问彼此工作内存中的变量,线程之间的变量传递需要自己的工作内存和主存之间的数据同步。
其实和操作系统里的问题一样。当一个线程修改一个变量时,它需要对其他线程可见。
除了时间片的引入,由于处理器优化和指令重排,CPU可能会乱序执行输入代码。例如,加载-添加-保存可以被优化为加载-保存-添加。这就是秩序的问题。
如下面的代码所示,逻辑是先初始化上下文,然后再做一些事情。
//线程1
boolean init=false(1)
string context=initial context();(2)
init=true(3)
//线程2
而(!init){ (4)
睡眠(1L);
}
context . do something();(5)但是如果出现了重新排序的情况,线程1先执行(1)和(3),那么此时线程2执行(4),操作在上下文初始化之前进行,这是有问题的。
volatile的底层实现级别
包含
Java源代码
Volatile int i关键字
字节码
ACC _易变
虚拟计算机
JVM内存屏障
操作系统
MESI原语支持总线锁。
java源代码其实看Java源代码,volatile其实就是一个关键词。
公开课{
私有静态易失起始ins=null
公共静态启动getInstance(){
if (ins==null){
synchronized (Start.class){
if (ins==null){
ins=new Start();
}
}
}
返回ins
}
公共静态void main(String[] args) {
system . out . println(1);
}
} Bycode从字节码的角度来看,它其实是一个变量上的标记。
JVM规范
仓库仓库员
易失性写操作
仓库装货工
装货工
易变操作系统缓存一致性协议MESI。
Lfence是一种负载障碍阅读障碍。在读取指令之前插入读取屏障会使高速缓存中的数据无效,并从主存储器重新加载数据。sfence是存储屏障写入屏障。在write指令后插入一个写屏障,可以将最新写入缓存的数据写回主存mfence,这是一个具有ifence和sfence能力的全方位屏障。参考https://www.bilibili.com/video/BV1QT4y1L7G9? p=5
版权归作者所有:原创作品来自博主CBeann,转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。