我有一个由多个线程使用的对象,但从不并发(总是只有一个线程在其上执行一个方法)。它包含几个非最终字段。现在我想知道是否必须将所有字段标记为volatile以确保下一个线程(可能以前使用过该对象)将看到更改。没有volatile,线程在什么时候从另一个线程获取更改?有保证吗?
如果我必须使用volatile,Akka如何解决这个问题?
幕后花絮Akka将在真实场景中运行多组演员 线程,通常许多actor共享一个线程,后续 一个演员的调用最终可能会被处理 线程。 Akka确保此实现细节不会影响 处理演员状态的单线程。
答案 0 :(得分:3)
没有需要制作成员变量volatile
,如果发生 - 之前在对象之外建立了关系。即使没有synchronized
块,也可以建立发生 - 之前的关系。以下示例为此目的使用volatile
- 保证编写者和读者不能同时访问同一个对象。在这种情况下,保证读者将读取正确的值。
class Foobar {
public static volatile Foobar instance = new Foobar(42);
public int value;
public Foobar(int value) { this.value = value; }
}
int reader() {
return Foobar.instance.value;
}
void writer(int value) {
Foobar.instance = new Foobar(value);
}
因此,有趣的部分是对象外部的代码 - 保证只有一个线程可以访问该对象。可以编写保证它的代码而无需建立发生在之前的关系。但是,这很奇怪,你应该在那里解决问题,而不是使成员变量volatile
。
答案 1 :(得分:1)
如果您可以确保一个线程和一个线程仅尝试同时访问该对象,那么仍然需要将该变量声明为volatile
,因为它会阻止每个线程保存"本地副本&#34 ;变量并随意更新。
阅读this article并注意可见性部分,它会让您更清楚地了解易失性的含义。
答案 2 :(得分:1)
没有volatile,线程可能会更改缓存中的对象,volatile会使线程刷新更改为内存。