手机wap网站是什么,莱芜买房网站,wordpress海报式分享,免费网站后台模版目录
1. volatile的两大特性
可见性#xff08;Visibility#xff09;
有序性#xff08;Ordering#xff09;
2. 四大屏障
3. 读写屏障插入策略
happens-before与volatile变量规则#xff1a;
注意事项
4. 原子性
5. 禁重排
6.使用场景
传统的单例模式实现如下…目录
1. volatile的两大特性
可见性Visibility
有序性Ordering
2. 四大屏障
3. 读写屏障插入策略
happens-before与volatile变量规则
注意事项
4. 原子性
5. 禁重排
6.使用场景
传统的单例模式实现如下多线程环境下会出问题
DCL单例模式实现 1. volatile的两大特性
可见性Visibility
当一个线程修改了一个volatile变量时新值会立即被写入主内存并且其他线程读取该变量时会从主内存中重新读取最新值。这确保了volatile变量的修改对其他线程立即可见。
有序性Ordering
volatile可以禁止对声明为volatile的变量前后的操作进行指令重排序优化。即编译器和处理器不会对volatile变量前后的操作进行重排序保证代码的执行顺序与程序代码顺序相同。 2. 四大屏障 LoadLoad屏障 作用在Load1之后和Load2之前插入LoadLoad屏障确保Load1数据的读取操作在Load2及后续读取操作之前完成。目的防止处理器将后面的读操作提前到前面的读操作之前。 StoreStore屏障 作用在Store1之后和Store2之前插入StoreStore屏障确保Store1的写入操作在Store2及后续写入操作之前完成。目的防止处理器将后面的写操作提前到前面的写操作之前。 LoadStore屏障 作用在Load操作之后和Store操作之前插入LoadStore屏障确保Load操作的数据读取在Store操作的数据写入之前完成。目的防止处理器将写操作提前到读操作之前。 StoreLoad屏障 作用在Store操作之后和Load操作之前插入StoreLoad屏障确保Store操作的数据写入在Load操作的数据读取之前完成。目的这是所有屏障中最强大的一个它不仅保证了屏障前后的读写操作的顺序还保证了屏障前的写操作对屏障后的读操作可见。
在volatile变量的读写场景中具体会用到以下屏障 读操作 在读取volatile变量之前会插入一个LoadLoad屏障和一个LoadStore屏障用来防止读取操作被重排序。 写操作 在写入volatile变量之后会插入一个StoreStore屏障和一个StoreLoad屏障用来确保写入操作对其他线程立即可见。
这些内存屏障保证了volatile变量在多线程环境下的可见性和有序性是JVM底层对Java内存模型JMM的一种实现。需要注意的是这些屏障的实现细节依赖于具体的CPU架构和JVM的版本。 3. 读写屏障插入策略
happens-before与volatile变量规则
第一个操作第二个操作普通读写第二个操作volatile读第二个操作volatile写普通读写可以重排可以重排不可以重排volatile读不可以重排不可以重排不可以重排volatile写可以重排不可以重排不可以重排 注意事项
屏障的顺序性屏障确保了操作的顺序性防止了重排序的发生这对于维护多线程之间的内存可见性至关重要。性能影响由于屏障会阻止指令的重排序这可能会对程序的性能产生一定的影响。因此应该只在确实需要保证可见性和有序性的情况下使用volatile变量。JVM和CPU架构差异不同的JVM实现和不同的CPU架构可能会对屏障的实现有所不同但它们都必须遵守Java内存模型JMM的规范。 4. 原子性
volatile的变量复合操作不具有原子性
在多线程环境中如果你需要一个复合操作具有原子性仅仅使用volatile是不够的。你需要使用锁或其他原子操作机制来确保操作的原子性。 5. 禁重排
为了防止指令重排序可以使用volatile关键字、锁如synchronized这些机制来禁止重排序。
volatile只是确保了可见性但是无法保证多个线程可能会同时读取同一个volatile变量的值然后基于这个值进行计算并写回新值导致结果不正确。需要通过加锁的方式解决。 6.使用场景
单一赋值例如i10这种操作可以但是复合运算例如类似i这种操作不可以状态标识判断业务是否结束开销较低的读操作写读策略DCL双端锁的发布
DCLDouble-Checked Locking是一种优化单例Singleton模式的方法旨在减少创建单例对象时同步代码块的开销。在传统的单例模式实现中为了保证单例的唯一性通常会使用一个同步块来确保在多线程环境中只有一个线程能够创建实例。
传统的单例模式实现如下多线程环境下会出问题
public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数防止外部创建实例}public static Singleton getInstance() {if (instance null) {synchronized (Singleton.class) {if (instance null) {instance new Singleton();}}}return instance;}
}DCL单例模式实现
DCL单例模式试图通过减少同步块的使用来优化性能。它的核心思想是先检查实例是否已经创建如果没有创建再使用同步块来创建实例。这样可以避免在实例已经创建的情况下多次执行同步块。
public class Singleton {private static volatile Singleton instance;private Singleton() {// 私有构造函数防止外部创建实例}public static Singleton getInstance() {if (instance null) { // 第一次检查synchronized (Singleton.class) { // 加锁if (instance null) { // 第二次检查instance new Singleton(); // 创建实例}}}return instance;}
}