zoukankan      html  css  js  c++  java
  • 图解volatile

      volatile是什么

        出去面试的时候,很多面试官都会问你:说说你对volatile的理解。

        下面我将用图的方式告诉大家,volatile是什么?

         

        如上图所示:每个线程都有自己的工作内存,同时还能访问共享内存。

        当两个线程,他们的代码都i需要读取X的值时候, 那么他都会从主内存里加载X变量到自己的工作内存,然后才可以使用X。

        这样,在线程的代码运行过程中,对X的值就可以直接从工作内存中加载了,不需要再从主内存中加载了。

        那么问题来了,为啥每次一定要让线程从工作内存的来读取变量的副本呢,而不是直接去读取共享内存的变量值X不行吗?

          因为线程运行的代码是对应一些指令,是CPU执行的,但是CPu每次执行指令运算,也就是执行我们写的那一大坨代码的时候,是要每次修改这个变量的值的,都是从主内存加载,性能会变差。

          线程内有自己的工作内存的概念,类似于一个本地的缓存,性能会很大提升。

        我们来设想一下,如果线程一,修改了X的值为1,然后将这个修改写入自己的工作内存,那么此时线程1的工作内存值为1.

        而主内存的X还是0,线程2的X还是0,怎么办呢?

         

        如上图所示,线程1和线程2其实都在操作X,但是线程1修改了X,线程2看不到,一直都是看到自己本地工作内存中一个副本的值!

        这就是Java并发编程的可见性问题:

        多个线程并发读写一个共享变量的时候,有可能某个线程修改了变量的值,但是其他线程看不到,也就是对其他线程不可见。

      volatile的作用及背后的原理

        要解决并发编程中的可见性问题,那要怎么办呢,你只要给这个变量定义的加上一个volatile,那么就可以解决了。

        volatile的作用啥是?

          1、一旦X变量定义了volatile来修饰的话,那么线程1,只要修改了X的值,就会在修改完自己工作内存的X变量之后,强制将这个X的值刷新到主内存,必须让主内存的值变成最新的值,整个过程如下图所示:

          2、其二,如果此时有别的线程的工作内存中有这个X变量的本地缓存,也就是一个变量副本的话,那么会让其他线程的工作内存X变量缓存直接失效过期,不允许再次读取和使用,如下图所示:

          3、如果线程2在代码运行中,再次需要读取X变量的值,那么尝试从本地工作内存读取,会发现这个X=0已经过期了。

          也就是必须重新从主内存中加载变量最新的值,那么不就可以读取到X=1的最新的值,整个过程如下图所示:

        对于一个变量加了volatile关键字修饰之后,只要一个线程修改了这个变量的值,立马会强制刷新回主内存,接着强制过期其他线程的工作内存的缓存,最后其他线程读取变量的时候,强制从主内存加载最新的值。

        这样就保证了,任何一个线程修改了变量的值,其他线程立马就可以看见了。

      总结&提醒

        volatile的主要作用还是保证可见性以及有序性。

        有序性涉及到指令重排,内存屏障等概念,但是volatile还是不能保证原子性的。

        也就是说,volatile主要解决一个线程修改了变量的值后,其他线程可以立马读取到最新的值。

        但是如果多个线程同时修改一个变量的值,那还是会可能出现多线程并发安全问题,导致数据修改错乱,也就是说volatile是不负责解决这个问题,也就是不负责解决原子性问题。

        原子性问题主要依靠synchronized,ReentrantLock等加锁机制来解决。

    终极目标:世界大同
  • 相关阅读:
    b_lc_带阈值的图连通性(反向思维+并查集)
    b_lc_无矛盾的最佳球队(排序+LIS)
    b_lq_子串分值(记录当前字符的出现的前一个位置+组合数学)
    多测师讲解python _课堂练习题梳理_高级讲师肖sir
    多测师讲解python _常见的正则表达式_高级讲师肖sir
    多测师讲解 _python常见的加密方式_高级讲师肖sir
    多测师讲解python _100道题_高级讲师肖sir
    前端 CSS 一些标签默认有padding
    前端 CSS 盒子模型
    Linux ulimit 命令 限制系统用户对 shell 资源的访问
  • 原文地址:https://www.cnblogs.com/gdouzz/p/14458063.html
Copyright © 2011-2022 走看看