Volatile1、保证可见性package com.sw.volatileDemo; import java.util.concurrent.TimeUnit; /** * @Author suaxi * @Date 2021/2/19 22:07 */ public class JMMTest { //不加volatile程序会死循环 //加上volatile保证了可见性 private volatile static int num = 0; public static void main(String[] args) { //main线程 new Thread(() ->{ //线程1 while (num == 0){ } }).start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } num = 1; System.out.println(num); //输出num=1，main线程将num改为1后，线程1还在循环while(num == 0) } } 2、不保证原子性原子性：任务在执行的过程中不能被分割，也不能被干扰，一组操作要么都成功，要么都失败不保证原子性测试实例：package com.sw.volatileDemo; /** * @Author suaxi * @Date 2021/2/19 22:25 * volatile不保证原子性 */ public class VolatileTest01 { private volatile static int num = 0; public static void add() { num++; } public static void main(String[] args) { for (int i = 0; i < 20; i++) { new Thread(() ->{ for (int j = 0; j < 1000; j++) { //理论上默认相加的结果等于2000 add(); } }).start(); } while (Thread.activeCount() > 2){ //Java中main线程和gc线程默认运行 Thread.yield(); } System.out.println(Thread.currentThread().getName()+" "+num); //19359 //18089 //不使用锁的实际相加的情况不等于2000 //volatile不保证原子性 } } 如何在不使用synchronized和lock锁的情况下保证原子性？图片来源：狂神说Java答：使用原子类解决package com.sw.volatileDemo; import java.util.concurrent.atomic.AtomicInteger; /** * @Author suaxi * @Date 2021/2/19 22:25 * volatile不保证原子性 * 使用Atomic原子类解决原子性问题 */ public class VolatileTest02 { private volatile static AtomicInteger num = new AtomicInteger(); public static void add() { //num++; num.getAndIncrement(); //AtomicInteger中的 +1 方法 } public static void main(String[] args) { for (int i = 0; i < 20; i++) { new Thread(() ->{ for (int j = 0; j < 1000; j++) { //理论上默认相加的结果等于2000 add(); } }).start(); } while (Thread.activeCount() > 2){ //Java中main线程和gc线程默认运行 Thread.yield(); } System.out.println(Thread.currentThread().getName()+" "+num); } } 3、禁止指令重排指令重排：源代码 ---> 编译器优化的重排 ---> 指令并行也可能会重排 ---> 执行假设x y a b四个数的默认值为0线程1线程2x = ay = bb = 1a = 2正常的执行结果为：x=0,y=0线程1线程2b = 1a = 2x = ay = b指令重排可能导致的结果：x =2，y=1Volatile可以避免指令重排：内存屏障，作用：1、保证操作的执行顺序2、保证某些变量的内存可见性