轻松理解java中的volatile关键字

volatile是什么?

volatile是java中的一个关键字; 它可以用来修饰成员变量;被它修饰的变量可以保证可见性.

什么是可见性?

可见性是指多个线程访问同一个共享变量时, 如果某个线程对共享变量进行了修改, 那么其他线程读取到的必须是修改后的值.这就是可见性.
先来看看常见的可见性问题:

class Game extends Thread {
    public int index = 0;

    public void setIndex(int index) {
        this.index = index;
    }

    public int getIndex() {
        return index;
    }

    @Override
    public void run() {
        System.out.println("Game Start");
        while (true) {
            if (getIndex() == -1) {
                break;
            }
        }
        System.out.println("Game End");
    }

    public static void main(String[] args) {
        Game game = new Game();
        game.start();
        try {
            Thread.sleep(1000);
        } catch (Exception e) {

        }

        game.setIndex(-1);
        System.out.println("change.....");
    }

}

主线程修改后的值没有被子线程读取到,所以结果会是一个死循环
在这里插入图片描述

当使用volatile关键字修饰index变量之后, 程序可以正常退出
在这里插入图片描述

volatile 怎么保证有序性和可见性?

可见性:
volatile的两条实现原则:

  1. Lock前缀指令会引起处理器缓存会写到内存,
    当对volatile变量进行写操作的时候,JVM会向处理器发送一条lock前缀的指令,将这个缓存中的变量回写到系统主存中
  2. 一个处理器的缓存回写到内存会导致其他处理器的缓存失效, 处理器使用嗅探技术保证内部缓存, 系统内存和其他处理器的缓存的数据在总线上保持一致。

综合上面两条实现原则,我们了解到:如果一个变量被volatile所修饰的话,在每次数据变化之后,其值都会被强制刷入主存。而其他处理器的缓存由于遵守了缓存一致性协议,也会把这个变量的值从主存加载到自己的缓存中。因此当有线程对变量进行修改之后, 其他线程读取到的都是修改之后的值; 这就保证了可见性;

有序性:
volatile 禁止了JVM的重排序, 禁止了重排序,就不存在有序性的问题了.

volatile能保证原子性么?

不能.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值