(1)volatile是如何保证可见性和禁止重排序?
(2)volatile的实现原理?
(3)volatile保证原子性吗?
一个volatile变量自身具有以下三个特性:
volatile靠内存屏障实现可见性和禁止重排序。
那么禁止指令重排序又是如何实现的呢?答案是加内存屏障。JMM为volatile加内存屏障有以下4种情况:
拿i++举例,看到i++被分解成了四条指令
getstatic //获取i当前的值并入栈 iconst_1 //入栈int类型的值1 iadd //将栈顶的两个值相加 putstatic //将相加的结果写回到i中
iconst_1和iadd在执行的过程中,这时并没有重新读取主内存中的最新值,可能i的值已经被其他线程修改了。所以volatile在i++这个场景中并不能保证其原子性
volatile是在synchronized性能低下的时候提出的。如今synchronized的效率已经大幅提升,所以volatile存在的意义不大。
volatile关键字是java提供的轻量级同步机制,保证了线程变量的可见性,和禁止指令重排。但不保证原子性。jvm创建线程时,都会为每个线程创建一个工作内存,工作内存是每个线程私有的。但是java规定所有的变量都存在主内存中。而单独的线程对变量的操作必须在工作内存中进行,所以首先要将变量从主内存中拷贝到自己的工作内存,然后对变量进行操作,操作完成后再将变量写回主内存****。因此不同的线程不能访问对方的线程,线程间的传值必须通过主内存来完成。
(1)volatile关键字可以保证可见性;
(2)volatile关键字可以保证有序性;
(3)volatile关键字不可以保证原子性;
(4)volatile关键字的底层主要是通过内存屏障来实现的;
(5)volatile关键字的使用场景必须是场景本身就是原子的;