共计 819 个字符,预计需要花费 3 分钟才能阅读完成。
Java 语言提供了一种稍弱的同步机制,即 volatile 变量,用来确保将变量的更新操作告诉到其余线程。当把变量申明为 volatile 类型后,编译器与运行时都会留神到这个变量是共享的,因而不会将该变量上的操作与其余内存操作一起重排序。volatile 变量不会被缓存在寄存器或者对其余处理器不可见的中央,因而在读取 volatile 类型的变量时总会返回最新写入的值。
在拜访 volatile 变量时不会执行加锁操作,因而也就不会使执行线程阻塞,因而 volatile 变量是一种比 sychronized 关键字更轻量级的同步机制。
当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到 CPU 缓存中。如果计算机有多个 CPU,每个线程可能在不同的 CPU 上被解决,这意味着每个线程能够拷贝到不同的 CPU cache 中。
而申明变量是 volatile 的,JVM 保障了每次读变量都从内存中读,跳过 CPU cache 这一步。
当一个变量定义为 volatile 之后,将具备两种个性:
1. 保障此变量对所有的线程的可见性,这里的“可见性”,如本文结尾所述,当一个线程批改了这个变量的值,volatile 保障了新值能立刻同步到主内存,以及每次应用前立刻从主内存刷新。但一般变量做不到这点,一般变量的值在线程间传递均须要通过主内存(详见:Java 内存模型)来实现。
2. 禁止指令重排序优化。有 volatile 润饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个 内存屏障(指令重排序时不能把前面的指令重排序到内存屏障之前的地位),只有一个 CPU 拜访内存时,并不需要内存屏障;(什么是指令重排序:是指 CPU 采纳了容许将多条指令不按程序规定的程序分开发送给各相应电路单元解决)。
volatile 性能:
volatile 的读性能耗费与一般变量简直雷同,然而写操作稍慢,因为它须要在本地代码中插入许多内存屏障指令来保障处理器不产生乱序执行。