volatile是否会阻塞或涉及上下文切换?

时间:2012-02-27 16:53:36

标签: java multithreading concurrency

最初我认为volatile变量比synchronized关键字好,因为它不涉及BLOCKING或CONTEXT SWITCHING。但是阅读this我现在很困惑。

是否使用低级原子锁或无阻塞方法实现volatile?

5 个答案:

答案 0 :(得分:5)

  

是否使用低级原子锁或无阻塞方法实现volatile?

Volatile的实现在每个处理器之间有所不同,但它是一个非阻塞的字段加载/存储 - 它通常通过内存栅栏实现,但也可以使用缓存一致的协议进行管理。

我刚读过那篇文章。这张海报在他对Volatile vs Synchronized流程的解释中实际上是不正确的,有人纠正了他作为评论。易失性不会保持锁定,您可能会发现易失性存储类似于同步发布,易失性负载类似于同步获取,但这仅与内存可见性有关,而与实际实现细节无关

答案 1 :(得分:5)

  

是否使用低级原子锁或无阻塞方法实现volatile?

使用volatile在相关领域周围竖起记忆障碍。这不会导致线程进入“阻塞”状态。但是,当访问volatile字段时,程序必须刷新对中央内存的更改并更新需要周期的高速缓存内存。 可能导致上下文切换,但不一定导致

答案 2 :(得分:3)

volatile确实不会导致阻塞。

然而,声明

  

volatile变量优于synchronized关键字,因为它没有   涉及阻止或上下文切换。

是非常有争议的,在很大程度上取决于你想要做什么。 volatile不等同于锁,并且声明变量volatile不会对涉及该变量的操作的原子性提供任何保证,例如增量。

volatile的作用是阻止编译器和/或CPU执行特定变量的指令重新排序或缓存。这被称为记忆围栏。需要这个令人讨厌的小机制来确保在多线程环境中读取特定变量的所有线程都具有其值的最新视图。这称为可见性,与原子性不同。

只能通过使用锁(synchronized)或原子基元在一般情况下保证原子性。

然而,令人困惑的是,使用同步机制还会生成隐式内存栅栏这一事实,因此如果您只是在synchronized块内读取/写入它,则声明变量volatile是多余的。

答案 3 :(得分:1)

Volatile是一个java语言修饰符,它提供保证的方式归结为JVM实现。如果将原始字段设置为volatile,则可以保证简单,您可以保证无论该字段读取该字段,它都将读取最新值。它基本上禁止任何JVM幕后优化,并强制所有线程跨越内存屏障来读取volatile原语。

答案 4 :(得分:0)

阻止意味着线程在阅读相同的volatile变量时不会互相等待,而不会相互排斥。然而,它们会触发硬件级别的围栏以观察"发生之前"语义(没有内存重新排序)。

为了使这一点更加清晰,volatile变量是非阻塞的,因为无论何时同时读取/多个线程,与其线程相关的CPU核心直接与主存储器通信或通过CPU缓存一致性(取决于硬件/ JVM实现)并且没有实施锁定机制。

<强>上下文切换 volatile关键字不会从其语义触发上下文切换本身,但可能并且取决于较低级别的实现。