关于volatile与synchronized

两个概念:
可见性
在一个线程中修改了变量的值 该变量能立刻回显到主线程中,确保其他线程也能看待该变量的修改
原子性
代码执行会一步到位,不会被其他操作影响到当前

1.volatile

只能用来修饰变量,常用于修饰可能同时被多个线程同时访问的变量
volatile 可以保证变量的有序性(底层禁用指令重排序) 但不具有原子性
被volatile修饰的变量改变后会立即同步到主内存保证变量的可见性

在双重检查单例模式中加volatile的原因:
在 instance = new Singleton() 初始化过程中 会被分成三步执行
1.给Singleton的实例分配内存
2.调用Singleton()的构造函数,初始化成员字段
3.将instance对象指向分配的内存空间
由于Java编译器允许处理器乱序执行,上述顺序可能是1-2-3 或1-3-2
在1-3-2时若在线程A中执行完3 22位执行时 切换到线程B 此时instance对象已不为空 所以线程B直接取用instance 成员字段未初始化 在使用时会发生错误 DCL失效
而添加volatile 禁用了变量的指令重排序保证了顺序执行且使得instance每次都从主内存中读取

扩展:
解决 多核CPU 高速缓存中数据不同步问题

2.synchronize

synchronize还可以保证变量的同步性和原子性
在jvm虚拟机中使用Monitor对象来实现方法同步和代码块同步。
Monitor本质是使用互斥锁来实现,保证同一时间只有一个线程来访问该对象
线程在加锁时工作顺序:
先清空工作内存→在主内存中拷贝最新变量的副本到工作内存→执行完代码→将更改后的共享变量的值刷新到主内存中→释放互斥锁

你可能感兴趣的:(关于volatile与synchronized)