JUC_Volatile Bertha 。 2023-03-13 05:49 89阅读 0赞 ### 文章目录 ### * 与synchronized的区别 * 保证可见性 * * 不加volatile,死循环 * 不保证原子性 * 禁止指令重排 * 单例模式DCL使用到volatile # 与synchronized的区别 # * volatile是线程同步的轻量级实现,性能比synchronized好 * volatile只能修饰变量,synchronized可以修饰方法和代码块 * volatile不会发生阻塞,synchronized可能会发生阻塞 * volatile保证数据可见性,不保证原子性,synchronized都保证 * volatile只要用于解决变量在多个线程之间的可见性,synchronized解决的是多个线程之间访问资源的同步性 # 保证可见性 # ## 不加volatile,死循环 ## import java.util.concurrent.TimeUnit; public class VolatileDemo { int i = 0; public static void main(String[] args) { VolatileDemo volatileDemo = new VolatileDemo(); new Thread(()->{ try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } volatileDemo.i=100; },"a").start(); while (volatileDemo.i==0){ } System.out.println(volatileDemo.i); } } # 不保证原子性 # public class VolatileDemo { volatile int i = 0; public static void main(String[] args) { VolatileDemo volatileDemo = new VolatileDemo(); for (int i = 0; i < 20; i++) { new Thread(() -> { for (int j = 0; j < 10000; j++) { volatileDemo.i++; } }, String.valueOf(i)).start(); } while (Thread.activeCount()>2){ Thread.yield(); } System.out.println(volatileDemo.i); } } ![在这里插入图片描述][20200511180622374.png] # 禁止指令重排 # volatile实现禁止指令重排优化,从而避免多线程环境下程序出现乱序执行的现象。 先了解一个概念,内存屏障(Memory Barrier)又称内存栅栏,是一个CPU指令,它的作用有两个: * 保证特定操作的执行顺序 * 保证某些变量的内存可见性 由于编译器和处理器都能执行指令重排优化。如果在指令之间插入一条memory barrier则会告诉编译器和CPU,不管什么指令都不能和这条memory barrier指令重排,也就说通过插入内存屏障禁止在内存屏障前后的指令执行重排优化,内存屏障的另一个作用是强制刷出各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NoaWxsX0x5bg_size_16_color_FFFFFF_t_70] # 单例模式DCL使用到volatile # public class SingletonDemo { private static volatile SingletonDemo instance; private SingletonDemo(){ System.out.println(Thread.currentThread().getName()+"\t 构造方法"); } /** * 双重检测机制 * @return */ public static SingletonDemo getInstance(){ if(instance==null){ synchronized (SingletonDemo.class){ if(instance==null){ instance=new SingletonDemo(); } } } return instance; } public static void main(String[] args) { for (int i = 1; i <=10; i++) { new Thread(() ->{ SingletonDemo.getInstance(); },String.valueOf(i)).start(); } } } [20200511180622374.png]: /images/20230312/a56cf9208efa40f1b9237690fade6734.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NoaWxsX0x5bg_size_16_color_FFFFFF_t_70]: /images/20230312/a3820ced61114a8ea0beaf7c781641c7.png
还没有评论,来说两句吧...