假设我有一个像这样的物体。
class Some {
synchronized void some() {
// do some with canceled
}
synchronized void setAsCanceled() {
canceled = true;
}
volatile boolean canceled = false; // package-private
}
现在,另一个对象可以更新canceled
。
class Other {
void setSomeAsCanceled() {
some.canceled = true; // Not calling the setAsCanceled()
}
private Some some = new Some();
}
直接更新canceled
volatile变量安全吗?还是应该调用setAsCanceled()
方法?
1条答案
按热度按时间fnvucqvd1#
当一个变量被创建和使用时,它也存在于一个缓存中。这个缓存并不总是同步的,特别是当你使用多线程时。当你把一个变量标记为
volatile
时,你告诉系统该高速缓存必须立即更新,这样其他使用它的人就可以得到更新后的值。另外,关键字volatile在现代编程语言中仍然有效,用于表示一个变量可以被多个线程或进程并发修改,这在使用共享内存或内存MapI/O的程序中尤其重要。
当一个变量被声明为volatile时,编译器和处理器会被指示以更高级别的谨慎来对待它,并避免某些可能干扰程序正确操作的优化。例如,编译器可能被阻止在寄存器中缓存变量的值,或对访问变量的指令进行重新排序。
volatile关键字在今天仍然重要的一个原因是现代处理器经常使用诸如无序执行和推测执行之类的技术来提高性能。这些技术可以使处理器以与指令在代码中出现的顺序不同的顺序来执行指令。如果程序员不小心的话,这会导致意外的行为。volatile关键字可以用来防止这种优化发生在特定的变量上,确保以可预测的方式访问变量。
总之,volatile关键字在今天仍然适用,因为它允许程序员控制在多线程或并发程序中如何访问和修改变量,这是编写在现代处理器上执行的高性能代码时的一个重要考虑因素。