作者:新视觉9927 | 来源:互联网 | 2022-04-22 01:52
区别:1、volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。2、volatile保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性。
区别:1、volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。2、volatile保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性。
考试先做会做的,不会做的后做。
public void mySort(){
int x = 11; //1
int y = 12; //2
x= x+5; // 3
y = x*x;//4
可能的顺序1234 2134 1324,不可能的属性4在1 和3前,因为有数据依赖性。
volatile禁止指令重排。
public class ReSortSeqDemo {
int a = 0;
boolean flag = false;
public void method01() {
a = 1; // flag = true;
// ----线程切换----
flag = true; // a = 1;
}
public void method02() {
if (flag) {
a = a + 3;
System.out.println("a = " + a);
}
}
}
如果两个线程同时执行,method01 和 method02 如果线程 1 执行 method01 重排序了,然后切换的线程 2 执行 method02 就会出现不一样的结果。
禁止指令排序
volatile 实现禁止指令重排序的优化,从而避免了多线程环境下程序出现乱序的现象
先了解一个概念,内存屏障(Memory Barrier)又称内存栅栏,是一个 CPU 指令,他的作用有两个:
保证特定操作的执行顺序
保证某些变量的内存可见性(利用该特性实现 volatile 的内存可见性)
由于编译器个处理器都能执行指令重排序优化,如果在指令间插入一条 Memory Barrier 则会告诉编译器和 CPU,不管什么指令都不能个这条 Memory Barrier 指令重排序,也就是说通过插入内存屏障禁止在内存屏障前后执行重排序优化。内存屏障另一个作用是强制刷出各种 CPU 缓存数据,因此任何 CPU 上的线程都能读取到这些数据的最新版本。
下面是保守策略下,volatile写插入内存屏障后生成的指令序列示意图:
使用顺序:Lock->同步代码块(已经进入了方法体,分配了相应资源)->同步方法(在方法体之外)。
更多编程相关知识,请访问:编程学习课程!!
以上就是volatile和synchronize的区别是什么?的详细内容,更多请关注其它相关文章!