Volatile关键字理解

Volatile定义

为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。

特点

volatile修饰的共享变量,能保证可见性,不能保证原子性

什么是可见性?

一个线程对共享变量值得修改,能够及时的被其他线程读取到。比如共享变量count=0;线程A修改为1,那么线程B拿到的count值应该是A修改过后的1,而不是0。

什么是原子性?

原子是世界上的最小单位,具有不可分割性。原子性就是某种操作,要么全部执行,要么都不执行。比如:银行转账的原子性,从A账户减1000元,给B账户加1000元,这2个操作要么全部执行,要么都不执行。

volatile实例

package com.thread;

/**
 * VolatileDemo类描述: 保证共享变量的“可见性”
 *      但是,不保证“原子性”
 *
 * @author yangzhenlong
 * @since 2018/1/21
 */
public class VolatileDemo extends Thread{
    private boolean  flag = true;

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public void run(){
        System.out.println("自定义线程...start...");
        while (flag){//当flag=true,线程不结束

        }
        System.out.println("自定义线程...end...");
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileDemo t = new VolatileDemo();
        t.start();
        Thread.sleep(3000);
        t.setFlag(false);
        System.out.println("-----------main线程-----------end");
    }
}

执行main方法后,发现3秒后,设置flag=false,自定义线程并没有停止

原因

如下图,每个为了更高效的执行计算,都有自己的本地内存(cpu高速缓存,也叫工作内存),程序启动时,每个线程都会从主存中拷贝共享变量flag到自己的本地内存中。而计算的操作也是在本地内存中取值的。当主线程修改了值并通知刷新主存后,自定义线程仍然读的是自己的本地内存的值为true,所以仍然执行,并未停止。

而volatile修饰后,主存发现共享变量的值发生改变后会及时通知自定义线程,自定义线程拿到的值flag=false,此时停止执行。

修改代码:

private volatile boolean  flag = true;

再次执行,3秒后,线程停止

原文地址:https://www.cnblogs.com/yangzhenlong/p/8325888.html

时间: 2024-08-05 12:00:15

Volatile关键字理解的相关文章

Java线程工作内存与主内存变量交换过程及volatile关键字理解

Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模型要区别于通常所说的虚拟机堆模型: 2. 线程独有的工作内存和进程内存(主内存)之间通过8中原子操作来实现,如下图所示: 原子操作的规则(部分): 1) read,load必须连续执行,但是不保证原子性. 2) store,write必须连续执行,但是不保证原子性. 3) 不能丢失变量最后一次ass

Java volatile 关键字 理解

Java   volatile 理解 Volatile 1 如果一个字段被申明为volatile,那么Java内存模型则可以保证多个线程所看到的值是一致的. 2  禁止指定重排. 3  volatile只能保证可见性,不能保证原子性 可见性实现原理: volatile能够保证可见性,那么它是如何实现可见性的呢?以X86处理器为例,在对volatile修饰的变量进行写操作时,通过编译器生成反汇编指令后,会发现会多一条Lock前缀,就是由于这条Lock前缀所实现的可见性.Lock前缀在多核处理器中会

volatile关键字、原子性和可见性

1.volatile关键字 理解volatile的关键首先要理解处理器缓存和主存. 如果将一个域声明为volatile,那么只要对这个域产生了写操作,那么所有读操作都可以看到这个修改,即volatile域的写操作会向主存刷新. 同步synchronized也会导致向主存中刷新,所以如果一个域完全由synchronized保护就不必设置为volatile. 2.原子性和可见性 可见性: 原子性:

volatile变量理解 via《Java并发编程实战》

第3章:对象的共享 volatile关键字的理解 volatile变量,用来确保将变量的更行操作通知到其他线程.当变量申明为volatile类型后,编译器与运行时都会注意带这个变量时共享的,因此不会将该变量上的操作与其他内存操作一起重新排序.volatile变量不会被缓存到寄存器或者其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新的写入值.可以把volatile关键字理解为java的弱同步机制(相比于synchronized).volatile还能保证64位读/写操作的

理解java中的volatile关键字

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了 实现代码线程的安全性.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分. volatile 写和读的内存语义: 线程 A 写一个 volatile 变量,实质上是线程 A

深入理解JVM读书笔记五: Java内存模型与Volatile关键字

12.2硬件的效率与一致性 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲:将运算需要使用到的数据复制到缓存中,让运算能快速进行,当运算结束后再从缓存同步回内存之中,这样处理器就无须等待缓慢的内存读写了. 基于高速缓存的存储交互很好地理解了处理器与内存的速度矛盾,但是也为计算机系统带来了更高的复杂度,因为它引入了一个新的问题: 缓存一致性(Cache Coherenc

说说我对java中volatile关键字的理解

首先引用两篇其他作者的文章:1.http://www.infoq.com/cn/articles/ftf-java-volatile    2.http://blog.csdn.net/hupitao/article/details/45227891 “volatile关键字能保证每个线程能读到最新的变量值”,要理解这句话首先明确cpu,寄存器,内存之间的关系.引用文中的一段话: 有volatile变量修饰的共享变量进行写操作的时候会多第二行汇编代码,通过查IA-32架构软件开发者手册可知,lo

关于Volatile关键字含义的一些个人理解

Volatile关键字出现在一些高级语言中,尤其是支持多线程编程的语言,比如C.C++.Java和C#.这些语言赋予了Volatile关键字不同的含义,但是总的来说,引入该关键字的出发点应该都是类似的. 在将volatile关键字之前,我们先了解一下计算机的缓存系统.根据不同的读取速度,计算机的存储器可以分为disk.memory.cache和register几大类.读写速度依次递增,存储容量依次递减.当然cache还能进一步细分成几级,如一级缓存.二级缓存和三级缓存,缓存还包括缓存命中(cac

java并发编程--深入理解volatile关键字

??volatile是一个在java并发编程中耳熟能详的关键字.即使从来没有使用过,你也偶尔会在技术书籍或博客中见到.对volatile关键字的解释常常被一笔带过:被修饰的变量具有可见性,但不能保证原子性.但是到底如何保证可见性,可见性是什么--诸如此类的问题在碰到这种凝练的解释时会产生一种知其然不知其所以然的困惑.那么我将尽力在这一篇文章中将volatile关键字的意义彻底击穿. 可见性 ??可见性,顾名思义,可见程度.假如你在被窝里打开了手电筒,只有你自己知道手电筒打开了,那么可见性就非常差