volatile关键字及其作用
一、多线程并发编程主要围绕三个特性实现。 可见性
可见性意味着当多个线程访问同一共享变量时,一个线程可以更改该变量的值,而另一个线程可以立即看到更改的值。
原子性
原子是指一个操作或一系列操作是全部执行还是不全部执行。
有序性
有序性是指程序运行的顺序按照代码的优先级执行。
二、volatile除了解决共享变量的可见性外,还有其他作用吗? 除了使共享变量可见外,volatile还具有规则性(禁止对指令进行排序)。
三.列举几个实际volatile实际项目中的例子? 1 .状态标志
例如,在我们的项目中,经常使用识别程序是否启动、初始化是否完成、是否停止等的变量。 volatile适用于只有一个线程修改,其他线程读取的情况。 当volatile变量更改时,它将立即显示在其他线程中。
如果不进行volatile修饰,会有什么结果? 例如,这是一个具有前端交互的系统,有a、b两个线程,用户单击停止APP应用程序按钮,调用a线程为shutdown )方法,将变量shutdown从false转换为true 但是,由于没有使用volatile限定,b线程无法感知shutdown的变化,可能会继续运行doWork中的循环,如果shutdown变量为true,则APP应用程序应该停止,doWork函数2 .调皮的热狗式单模
使用volatile限定时,singleton的实例化将在所有线程中立即显示。
1 .为什么使用volatile修饰singleton引用,以及是否用synchronized锁定?
volatile仅保证共享变量singleton的可见性,但singleton=new Singleton (; 这个操作不是原子,而是分为三个步骤。
步骤1 )向堆内存申请内存空间;
步骤2 :初始化申请的内存区域
步骤3 :为singleton分配内存空间地址;
所以singleton=new Singleton (); 是由三个操作组成的复合操作:在多线程环境中,a线程执行第一步、第二步后发生线程切换,b线程开始执行第一步、第二步和第三步。 由于a线程singleton尚未赋值,因此可以使用同步来锁定此代码块,以确保这三个步骤不会中断。
2 .第一次检查singleton清空后,为什么内部需要第二次检查?
a线程进行空判断检查后,开始执行同步代码块时发生线程切换,b线程也进行空判断检查,b线程检查singleton==null的结果是否为true,返回同步使两个线程串行运行,但如果
3.volatile是否有内存可见性以外的作用?
用volatile限定的变量不仅可以看到,还可以防止指令重新排序。
指令排序是编译器和处理器为了优化程序的执行性能而对指令序列进行排序的手段。 症状是CPU执行指令的顺序可能与程序代码的顺序不一致。 例如,a=1; b=2; CPU有可能先执行b=2后执行a=1;
singleton=new Singleton (; 这是三个步骤的组合,如果不使用volatile限定,可能会发生指令排序。 步骤3在步骤2之前执行,其中singleton引用尚未初始化的内存区域,并且如果另一个线程调用单个实例的方法,则导致未初始化的错误。
命令的排序也遵循一定的规则。
排序不会对依赖关系的操作进行排序
排序的目的是优化性能,无论如何排序,单线程程序运行的结果都不会改变。
因此,volatile还具有禁止命令重新排列的作用。