Java中的volatile关键字
Posted fhdada
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的volatile关键字相关的知识,希望对你有一定的参考价值。
并发编程的三个基本概念:
- 原子性
- 可见性
- 有序性
编写多线程程序时,经常会看到 volatile 关键字。
在Java中,volatile 被用来修饰 变量。
使用 volatile 修饰的变量有什么特点呢?
JMM内存划分
在Java内存模型中,内存区域的划分大致如下图所示:
除了共享的 主内存 外,每个Java线程都有一块自己私有的工作内存。
当线程需要对 主存 中的变量进行读写时,会先从 主存 加载到自己的工作内存中,然后进行读写,再刷新到主存中去。
对于多次读取,如果工作内存中已经有缓存,就不会再去 主存 中加载了。
这就会导致:多线程下数据读取不一致的问题。
使用 volatile 修饰的变量,会让该变量在线程的工作内存中的缓存失效,每次读取时都去 主存 中加载。
volatile 可以保证可见性,但是不能保证原子性。
对于非原子操作,仅仅使用 volatile 仍然会有数据安全问题。
指令重排序
Java代码机器无法识别,要想运行,最终会被编译成一条条指令。
编译器在编译代码时,为了优化程序性能会自动将指令进行:重排序。
重排序的目的是为了 优化性能,但是不管指令如何重排,单线程下程序的运行结果都是一致的。
使用 volatile 修饰的变量,编译器会对其 禁止使用重排序。
使用场景
volatile 是Java提供的一种比 synchronized 更轻量级的一种同步机制。
它的安全性没有 synchronized 高,但是开销低。
变量的操作如果都是原子的,那么可以放心使用。
如果是非原子操作,例如:i++,就会存在数据安全问题。
适合的场景:
- 使用于 读多写少。
- 写操作不依赖当前值。
- 用作状态标记。
以上是关于Java中的volatile关键字的主要内容,如果未能解决你的问题,请参考以下文章