volatile关键字分析

2021-02-08  本文已影响0人  仩渧哋寵

关于线程的可见性

什么是线程间的可见性?
一个线程对共享变量值的修改,能够及时的被其他线程看到。

什么是共享变量?
如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。

什么是java内存模型?(Java Memory Model,简称JMM)
JMM描述了java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节。

  1. 规则1:
    1>所有的变量都存储在主内存中
    2>每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中该变量的一份拷贝)
  2. 规则2:
    1>线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写
    2>不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量的传递需要通过主内存来完成

示例代码

public class VisableDemo {
//volatile 解决可见性问题
  public volatile static boolean stop = false;

  public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(()->{
      int i = 0;
      while (!stop){
        i++;
      }
      System.out.println("result:"+i);
    });

    thread.start();
    System.out.println("begin start thread");
    Thread.sleep(10000);
    stop = true;

  }

}

Lock指令的作用:

什么时候需要用volatile?

当存在多个线程对同一个共享变量进行修改的时候,需要增加volatile,保证数据修改的实时可见。

指令重排序会导致运行顺序发生变化,如下图:


image.png

这两个方法运行顺序有可能不是顺序进行的,有可能会发生exeToCPU1()先执行,造成了value的值计算出现差错。

为了避免这种问题出现,cup层面做了处理:

内存屏障


image.png
上一篇 下一篇

猜你喜欢

热点阅读