我曾经相信两个线程之间共享的任何变量都可以在线程本地缓存,并且应该声明为 volatile。但这种信念最近受到队友的挑战。我们试图弄清楚在以下情况下是否需要 volatile。
class Class1
{
void Method1()
{
Worker worker = new Worker();
worker.start();
...
System.out.println(worker.value); // want to poll value at this instant
...
}
class Worker extends Thread
{
int value = 0; // Should this be declared as a volatile?
public void run()
{
...
value = 1; // this is the only piece of code that updates value
...
}
}
}
现在我的论点是,Worker(子)线程可能已经在线程中缓存了 Worker 对象的变量“值”,并在将值设置为 1 时仅更新了它的副本。在这种情况下,主线程可能看不到更新的值。
但是我的队友认为,由于对“值”的访问是通过对象(工作者)发生的,因此对于两个线程来说,看到不同的值,只有当两个线程都维护“工作者”对象本身的单独副本时才有可能(这进一步意味着创建线程涉及创建所有共享对象的深层副本)。
现在我知道这不可能是真的,因为每个线程维护所有共享对象的完全不同的副本是非常低效的。因此,我对此表示严重怀疑。在主线程中执行“worker.value”是否引用了与在子线程中执行“this.value”不同的内存位置?子(Worker)线程会缓存“值”吗?
问候。