volatile-验证线程之间的可见性

因为JVM运行程序的实体是线程,而每一个线程建立时JVM都会为其建立一个工做内存(有些地方称为栈空间),工做内存是每一个线程的私有数据区域,而Java内存 模型中规定全部变量都存储在主内存,主内存是共享内存区域,全部线程均可以访问,但线程对变量的操做(读取赋值等)必须在工做内存中进行,首先要将变量从主内存拷贝的本身的工做内存空间,而后对变量进行操做,操做完成后再将变量写回主内存,不能直接操做主内存中的变量,各个线程中的工做内存中存储着主内存中的变量副木拷贝,所以不一样的线程间没法访问对方的工做内存,线程间的通讯(传值)必须经过主内存来完成,其简要访问过程以下图:java

 

代码验证以下:this

import java.util.concurrent.TimeUnit;

class MyData{
      //定义初始参数,volatile关键字使用为重点
      volatile int number = 0;
      //更改初始参数
      public void changeNumber(){
          this.number = 60;
      }
}
public class VolatileDemo {
    public static void main(String[] args) {
        //初始化资源类
        MyData myData = new MyData();
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName()+"初始化线程,初始参数为:"+myData.number);
            //AAA线程暂停三秒后
            try{
                TimeUnit.SECONDS.sleep(3);
            }catch(Exception e){
                e.printStackTrace();
            }
            //AAA线程更改初始化参数为60
            myData.changeNumber();
            System.out.println(Thread.currentThread().getName()+"线程更改初始化参数为:"+myData.number);
        },"AAA").start();

        while(myData.number == 0){
            //第二个线程是main线程,在number=0时则一直陷入死循环,当number=60时则打印主线程语句。
        }
        System.out.println(Thread.currentThread().getName()+"主线程当前参数:"+myData.number);
    }
}

结果展现:spa

1.初始参数number未加上volatile:线程

2.初始参数number加上volatile:code

总结:blog

volatile是JAVA虚拟机提供的轻量级的同步机制,volatile三大特征:保证可见性,不保证原子性,禁止指令重排。内存

相关文章
相关标签/搜索