博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于Java中volatile关键字笔记
阅读量:4490 次
发布时间:2019-06-08

本文共 1296 字,大约阅读时间需要 4 分钟。

volatile通常被认为是一种轻量级的synchronized,字面上它表示易变的,在并发编程中,它保证了共享变量的可见性。所谓可见性指的是,某个线程对变量进行操作后,其他线程能够读取到操作后的最新结果。

CPU通常不会直接与内存通信,内存中的数据首先会被读取到缓存中进行读写。当对声明了volatile的变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,表示将变量锁在的缓存行数据写回内存中。

当写一个volatile变量时,Java内存模型JMM会把线程对应的本地内存的共享变量刷新到主内存中

 

然而volatile并不能保证线程安全,来看下面的例子

public class VolatileTest {    private static volatile Integer num = 0;    public static void main(String[] args) throws InterruptedException {        Thread[] threads = new Thread[10];        for (int i = 0; i < 10; i++) {            threads[i] = new Thread(new Runnable() {                @Override                public void run() {                    for (int k = 0; k < 10000; k++) {                        num++;                    }                }            });            threads[i].start();        }        for (int i = 0; i < 10; i++) {            threads[i].join();        }        System.out.println(num);    }}

 

这一段代码的期望运行结果应当是输出100000,然而实际测试发现是一个小于100000的数字,说明voilatile不能保证++操作的原子性。

 volatile关键字修饰的变量被读或者被写是使用锁来同步,并且对于volatile修饰变量的读总是可以读到任意线程对这个变量(当时)最新的写入。但是对于读并且写这样的复合操作是不具有原子性的。

volatile关键字修饰的变量具有对其写happens-before对其读的规则,因此线程总能看见任意线程对此volatile变量最新的修改。

 

volatile变量具有的特性如下

可见性:总是能够读到任意线程对volatile变量最新的修改

原子性:对单个volatile变量的读或者写具有原子性,但复合操作如++不具有原子性

 

转载于:https://www.cnblogs.com/micrari/p/5627450.html

你可能感兴趣的文章
python 调用C++ DLL,传递int,char,char*,数组和多维数组
查看>>
C# 调Win32 API SendMessage简单用法及wMsg常量
查看>>
解决Python print输出不换行没空格的问题
查看>>
python使用内置方法和修饰器方法获取类名、函数名
查看>>
python 整数转字节 char
查看>>
基于EasyHook实现监控explorer资源管理器文件复制、删除、剪切等操作
查看>>
[Python]ctypes+struct实现类c的结构化数据串行处理
查看>>
Windbg使用
查看>>
GUID和UUID、CLSID、IID 区别及联系
查看>>
MFC ATL STL概要
查看>>
Hook基本知识
查看>>
Hook CreateProcess
查看>>
C#与C++之间类型的对应
查看>>
(C++C#类型互转工具)使用Signature Tool自动生成P/Invoke调用Windows API的C#函数声明...
查看>>
面试题
查看>>
Powershell + HTA
查看>>
IFG以太网帧间隙
查看>>
WINDOWS API 大全(一)
查看>>
Wmic
查看>>
WINDOWS API 大全(二)
查看>>