concurrent之volatile

以战养战,边学边练,方有所成

  volatile轻量级的同步机制,保证可见性,不保证原子性,禁止指令重排  

  今天就分析一下volatile的关键字,内存可见性,在讲这个之前,我们来看一下,线程是怎么去处理数据的,我们都知道线程是cpu调度的单位,每个线程都是稀缺资源,创建线程会消耗cpu缓存和cpu运算资源,cpu在创建线程之后,线程具有自己的工作空间,java中的变量都是保存在主内存中,如果线程需要操作主内存,那么就需要copy一份变量到自己的工作空间中,进行修改变量操作,操作完,再把操作后的数据写入到主内存,jmm就是控制线程和主内存的变量输入和输出操作,如果这个变量被多个线程操作,当一个变量操作完,如果没有内存可见性的操作,其他线程是不知道该变量被修改了

  总结:线程修改变量副本拷贝,发送给主线程,如果变量加了volatile,立马通知给其他线程该变量修改完成  

  原子性:保证数据完整一致性,中间过程不可被分割,要么成功,要么失败,没有原子性,有可能写覆盖

  指令重排序:必须满足数据依赖性,计算机在执行程序时,为了提高性能,对编译器优化重排,指令并行执行,内存系统重排

  禁止指令重排:通过插入内存屏障指令,禁止在内存屏障前后的指令执行重排序优化,避免线程执行乱序的情况

yield线程中的关键字,让出线程执行,让其他线程在准备中(Runnable),之后一起执行,Thread.activeCount(),一个程序运行必须有2个或以上线程,类线程和gc线程

  解决原子性问题:

  1. 加sync锁
  2. 如果是变量可以使用AtomicInteger      
private static volatile SingletonDemo singletonDemo = null;
    
    /**
     * 双端检锁
     * @return
     */
    private static SingletonDemo getSingleton(){
        if (singletonDemo == null){
            synchronized (SingletonDemo.class){
                if (singletonDemo == null){
                    singletonDemo = new SingletonDemo();
                }
            }
        }
        return singletonDemo;
    }

  

posted @ 2021-10-11 23:09  外科手术医生  阅读(30)  评论(0编辑  收藏  举报