volatile详解

1.什么是volatile?

volatile是java虚拟机提供的轻量级的同步机制,一共有三大特性,保证可见性,不保证原子性,禁止指令重排。

2.可见性

首先提一个JMM的概念,JMM是Java内存模型,它描述的是一组规范或规则,通过这组规范定义了程序中各个变量(实例字段,静态字段和构成数组对象的元素)的访问方式。JMM规定所有的变量都在主内存,主内存是公共的所有线程都可以访问,线程对变量的操作必须是在自己的工作内存中。在这个过程中可能出现一个问题。

在这里插入图片描述

现在假设主物理内存中存在一个变量他的值为7,现在线程A和线程B要操作这个变量所以他们首先要将这个变量的值拷贝一份放到自己的工作内存中,如果A将这个值改为1,这时候线程B要使用这个变量但是B线程工作内存中的变量副本是7不是新修改的1这就会出现问题。所以JMM规定线程解锁前一定要将自己工作内存的变量写回主物理内存中,线程加锁前一定要读取主物理内存的值。也就是说一旦A修改了变量值,B马上能知道并且能更新自己工作内存的值。这就是可见性。

3.volatile可见性代码证明

volatile可以保证可见性,及时通知其他线程,主物理内存的值已经被修改。我们用代码证明一下。

设计思路首先我们新建一个类里面有一个number,然后写一个方法可以让他的值变成60,这时候在主线程中开启一个新的线程让他3s后将number值改为60然后主线程写一个循环如果主线程能立刻监听到number值的改变则主线程输出改变后的值此时说明有可见性。如果一直死循环说明主线程没有监听到number值的更改说明不具有可见性。

class MyData{
   
    public int number = 0;
    public void change(){
   
        number = 60;
    }
}

public class VolatileTest {
   
    public static void main(String[] args) {
   
        MyData myData = new MyData();
        new Thread(()->{
   
            System.out.println(Thread.currentThread().getName() + "number is :"+ myData.number);
            try {
   
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            myData.change();
            System.out.println(Thread.currentThread().getName() + "has changed" + myData.number);
        },"A").start();
        while(myData.number == 0)
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温JZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值