Java——Volatile

目录

 

可见性问题

JMM (Java Memory Model)

现在计算机的内存模型

Java内存模型

可见性的解决方案

加锁

Volatile修饰共享变量

Volatile做了什么?

MESI (缓存一致性协议)

如何发现数据是否失效?——嗅探

嗅探的缺点——总线风暴

禁止指令重排序

无法保证原子性

volatile和sychronized的区别

应用

总结


可见性问题

首先给出一段代码:

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        while (true) {
            if (myThread.isFlag()) {
                System.out.println("TRUE");
            }
        }
    }
}

class MyThread extends Thread {
    private boolean flag = false;

    public boolean isFlag() {
        return flag;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;
        System.out.println("flag=" + flag);
    }
}

输出结果:

flag=true

结果显示,即使线程改变了flag变量,主线程也没能输出“TRUE”

为什么会出现这种情况?

JMM (Java Memory Model)

JMM:Java内存模型,是Java虚拟机规划中所定义的一种内存模型,Java内存模型是标准化的,屏蔽了底层不同计算机的区别(注意这个跟JVM不是一个东西)。

首先介绍一些现代计算机的内存模式:

现在计算机的内存模型

在早期计算机中CPU和内存的速度是差不多的,但是现代计算机中,CPU的指令速度远超内存的存取速度,由于计算机的存储设备和处理器的运算速度有几个数量级的差距,所以现代计算机系统都加入了一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲。

将运算需要使用的数据复制到缓存中,让运算能快速进行,当运算结束后再从换从同步回内存之中,这样处理器就无需等待缓慢的内存读写了。

基于高速缓存的存储交互很好地解决了处理器与内存的速度矛盾,但是也为计算机系统带来了更高的复杂度,因为它引入了一个新的问题:缓存一致性(Cache Coherence)

在多多力气系统中,每个处理器都有自己的告诉缓存,而它们又共享同一主内存。

Java内存模型

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

JMM有以下规定:

所有的共享变量都存储于主内存,这里所说的变量指的是实例变量和类变量,不包含局部变量,因为局部变量是线程私有的,因此不存在竞争问题。

每一个线程还存在自己的工作内存,线程的工作内存,保留了被线程使用的变量的工作副本。

线程对变量的所有的操作(读、取)都必须在工作内存中完成,而不能直接读写主内存中的变量。

不同内存之间也不能直接访问对方工作内存中的变量,线程间变量的值的传递需要通过主内存中转来完成。

本地内存与主内存的关系:

 正是因为这样,才导致了可见性问题的存在,那我们就讨论下可见性的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值