Java并发中volatile关键字

本文介绍了Java并发中volatile关键字的作用和原理。volatile提供轻量级同步机制,保证了可见性和有序性,但无法确保原子性。文章通过代码示例说明了volatile如何防止指令重排序,并解释了其底层的内存屏障和MESI缓存一致性协议如何实现这些特性。
摘要由CSDN通过智能技术生成

volatile关键字是什么

在并发编程中synchronized是阻塞式同步,在线程竞争激烈的时候,它会升级为重量级锁,而volatile是Java虚拟机提供的最轻量级的同步机制。

在Java内存模型当中,告诉我们,各个线程会将共享变量从主存中拷贝到工作内存,然后执行引擎会基于工作内存中的数据进行操作处理。

那在线程的工作内存进行操作后何时会写的主存中?这个时机对普通变量是没有规定的,而针对volatile修饰的变量Java虚拟机给予了特殊的约定。

volatile 这个变量具备两种特征:

1. 一种是保证该变量对所有的线程可见的,在一个线程修改了变量值之后,新的值对于其他线程是可以理解获取的。 2. 一种是volatile禁止指令重排,即volatile变量不会被缓存在寄存器中或者其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。 3. 但volatile不能保证对变量操作的原子性。

volatile实现可见性和有序性

因为在访问volatile 修饰的变量的时候,是不会执行加锁操作的,所以也意味着不会执行线程阻塞,因此volatile变量修饰的是一种比synchronized关键字更轻量级的同步机制,volatile 主要是适用于一个变量被多个线程共享,多个线程均可针对这个变量执行赋值或者读取操作。

在有很多线程对普通变量进行读写的时候,每个线程都首先需要将数据从内存中复制到CPU的缓存当中,如果计算机中有多个CPU,则线程可能都在不同的CPU中执行,这就意味着每个线程都需要将同一个数据复制到不同的CPU cache当中,这样在每个线程对同一个变量的数据做了不同的处理后就可能存在数据不一致的情况。

如果将变量声明了volatile,那么JVM就能保证每次读取变量时能直接从内存中读取,跳过CPU Cache这一步,有效的解决了多线程数据同步的问题。

下面我们就用代码演示一下volatile关键字修饰的可见性。
在这里插入图片描述

所以我们在这稍作修改,给我们需要读的变量添加上volatile变量,将它变为在其他线程是可读的。
在这里插入图片描述

代码:

public class ThreadDemo implements  Runnable{
   
   //volatile修饰的变量,在这表示一个线程中被修改后,对其它线程立即可见
    private volatile boolean  flag = false;//共享数据

    @Override
    public void run() {
   
        try {
   
            Thread.sleep(200);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        this.flag = true;//让一个线程修改共享变量值
        System.out.println(this.flag);
    }
    public boolean getFlag() {
   
        return flag
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值