Java 开发实战—一起来认识volatile机制

开发 前端
不论是求职面试还是项目实际开发,volatile都是一个需要掌握的知识点,今天,我们就一起来认识volatile机制,从实战中精进我们的能力吧。

现如今,我们处于一个新兴技术高速发展的时代,各个产业对于开发人员的需求更多、更高。因此,无论是在入门阶段还是进阶阶段都需要学习大量的专业知识,不断提高对Java的认识是必要的。

不论是求职面试还是项目实际开发,volatile都是一个需要掌握的知识点,今天,我们就一起来认识volatile机制,从实战中精进我们的能力吧。

[[404609]]

何为Volatile?为什么要用Volatile?

java是面向对象的高级编程语言,Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,volatile是Java提供的一种轻量级的同步机制。

在Java多线程的开发中有三种特性:原子性、可见性、有序性,使用volatile不会引起线程上下文的切换和调度,可以保证内存可见性和防止指令重排序。

基本用法

在Java语言里,volatile关键字是用来修饰变量的,方式如下入所示。表示:该变量需要直接存储到主内存中。

  1. public class SharedClass { 
  2. public volatile int counter = 0

被volatile关键字修饰的 int counter 变量会直接存储到主内存中。并且所有关于该变量的读操作,都会直接从主内存中读取,而不是直接从CPU缓存。

理解 volatile 关键字

对于初学者来说,volatile只是简单的了解,只知道volatile作用就是“保证可见性”、“禁止指令重排序”,但是仍然存在一些误区。

变量可见性问题(Variable Visibility Problem) : volatile可以保证变量变化在多线程间的可见性。

一个多线程应用中,出于计算性能的考虑,每个线程默认是从主内存将该变量拷贝到线程所在CPU的缓存中,然后进行读写操作的。现在电脑基本都是多核CPU,不同的线程可能运行的不同的核上,而每个核都会有自己的缓存空间。

volatile的出现,就是为了解决线程间不可见性,通过 volatile 修饰的变量,都会变得线程间可见。

解决多线程不可见的方式就是:

  • 通过 volatile 修饰的变量,所有关于该变量的读操作,都会直接从主内存中读取,而不是 CPU 自己的缓存。而所有该变量的写操都会写到主内存上。
  • 因为主内存是所有 CPU 共享的,理所当然即使是不同 CPU 上的线程也能看到其他线程对该变量的修改了。volatile不仅仅只保证 volatile变量的可见性,volatile 在可见性上所做的工作,实际上比保证 volatile 变量的可见性更多。

特性及原理

(1) 可见性

任意一个线程修改了 volatile 修饰的变量,其他线程可以马上识别到最新值。实现可见性的原理如下。

  • 步骤 1:修改本地内存,强制刷回主内存。
  • 步骤 2:强制让其他线程的工作内存失效过期。(此部分更多的属于MESI协议)

(2) 互斥性

同一时刻只允许一个线程操作 volatile 变量,volatile 修饰的变量在不加锁的场景下也能实现有锁的效果,类似于互斥锁。上面的 VolatileFeaturesA.java 和下面的 VolatileFeaturesB.java 两个类实现的功能是一样的(除了 getAndAdd 方法)。

(3) 部分有序性

JVM 是使用内存屏障来禁止指令重排,从而达到部分有序性效果,了解到内存屏障类型,我们就可以解决那些因重排序引起的有序性问题。

什么是内存屏障呢?内存屏障其实就是一个CPU指令,在硬件层面上来说可以扥为两种:Load Barrier 和 Store Barrier即读屏障和写屏障。主要有两个作用:

  • 阻止屏障两侧的指令重排序;
  • 强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效。

在JVM层面上来说作用与上面的一样,但是种类可以分为四种:

实现有序性的原理:

如果属性使用了 volatile 修饰,在编译的时候会在该属性的前或后插入内存屏障来禁止指令重排。

首先一个变量被volatile关键字修饰之后有两个作用:

  • 对于写操作:对变量更改完之后,要立刻写回到主存中。
  • 对于读操作:对变量读取的时候,要从主存中读,而不是缓存。

 

责任编辑:赵宁宁 来源: 今日头条
相关推荐

2012-04-14 20:47:45

Android

2012-06-25 09:37:24

Web

2012-09-10 13:42:55

PHP项目管理

2012-11-08 17:33:53

智慧云

2020-06-11 18:35:23

C++编程语言

2009-07-14 16:35:57

Swing组件大全

2021-09-09 08:47:52

Dependency 安全漏洞工具

2021-06-02 15:30:12

Synchronize并发多线程

2021-04-26 11:18:15

FedoraLinuxBug

2010-05-21 17:32:07

IIS服务器

2009-10-29 16:32:34

Oracle表空间

2011-09-07 22:59:07

联想一体机

2022-05-20 12:14:50

ZuulSpringClou

2010-05-10 15:31:35

Unix文件

2023-06-28 07:49:02

2021-01-20 15:31:00

区块链比特币数字货币

2014-02-11 11:21:00

html5工具

2012-07-10 09:14:51

Web

2009-09-09 09:23:37

服务器稳定性

2017-11-02 14:39:54

点赞
收藏

51CTO技术栈公众号