在Java多线程中,何时使用volatile关键字与同步机制?

15

在多线程中何时使用volatile关键字和同步锁?


https://dev59.com/VnA75IYBdhLWcg3wlqIT,快速搜索会显示很多相关信息。 - Umesh Awasthi
重复?https://dev59.com/6Gkw5IYBdhLWcg3wfKrZ - Yousha Aleayoub
3个回答

27

使用 volatile 关键字来确保每次读取变量时都能看到最新写入该变量的值。当需要值在多条指令中保持稳定时,请使用 synchronized 关键字。(请注意,这并不一定意味着多个语句;以下单个语句也是如此:

var++; // NOT thread safe!

volatile关键字修饰的var变量即使声明为线程安全,你需要执行以下操作:

synchronized(LOCK_OBJECT){var++;}

请看这里,了解此问题的简要概述。


AtomicLong使用方法和一个volatile字段处理var++。你能否编辑你的回答,提供更好的示例? - Gray
@Gray - 好的。我更好的例子是,varfloat 类型。 - Ted Hopp

10

Volatile只能确保在多个线程读取变量时,始终从内存中读取最新状态。但它不能保证任何写入安全性/操作顺序,即两个线程可以以任意随机顺序更新volatile变量。此外,它不能确保对变量的多个操作是原子操作。

然而,同步块可以确保最新状态和写入安全。在同步块中,对变量的访问和更新也是原子的。 然而,前提是必须使用相同的锁对象来访问/更新涉及到的变量,以便在任何时间点上,多个线程不能访问该变量。


3

这是一个非常广泛的问题。我能给出的最好答案是,在进行必须被其他线程视为原子性发生的多个操作时,使用synchronized - 要么所有步骤都已经发生要么没有一个发生。

对于单个操作,volatile可能足够了;它充当内存屏障以确保对其他线程的更改可见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接