import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicIntegerArray;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class VolatileTest { /** * volatile 是一个类型修饰符 * 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性) * 禁止进行指令重排序。(实现有序性) * volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。 */ //实现1 缓存一致性协议 //多个线程从主内存中读值到工作缓存,当其中一个线程中修改了工作缓存的数值,该数据会立即同步回主内存 //其他线程通过 主线嗅探机制 可以感知到数据的变化从而将自己缓存的数据失效// private static boolean flag = true; //底层通过一个汇编Lock前缀指令 实现的是缓存行锁 锁这块内存区域的缓存 数据会立即同步回主内存 private static volatile boolean flag = true; public static void main(String[] args) { List<Object> objects = Collections.synchronizedList(new ArrayList<>());// CopyOnWriteArrayList new Thread(() -> { while (flag) { } System.out.println("=======================Thread"); }).start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========================main"); flag = false; } //1.给对象分配内存空间 //2.初始化 主要涉及三种执行对象初始化的结构,分别是 实例变量初始化、实例代码块初始化 以及 构造函数初始化。 //3.指向刚分配的内存地址 此时实例 != null // 123 变 132 重排 即引用 volatileTest 指向内存memory时,这段崭新的内存还没有初始化 //双重检查机制 DCL //指令重排序 As-if-Serial 和 Happens-Before原则 //java语义分析不存在依赖就有可能进行重排序 //As-if-Serial:不管怎么重排序 ,单线程的执行结果不能改变 他不知道多线程重排序会影响其他线程的结果 //Happens-Before 八大原则 private static volatile VolatileTest volatileTest; private VolatileTest() {}; public static VolatileTest getVolatileTest(){ if (null == volatileTest) { synchronized (VolatileTest.class) { if (null == volatileTest) { volatileTest = new VolatileTest(); } } } return volatileTest; }}