Abh*_*ang 6 java concurrency multithreading 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
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的论点是,有可能Worker(子)线程可以缓存线程中Worker对象的变量"value",并在将值设置为1时更新它的副本.在这种情况下,主线程可能看不到更新的值.
但是我的队友认为,由于对"值"的访问是通过对象(worker)进行的,因此两个线程都可以看到不同的值,只有两个线程都维护"worker"对象本身的单独副本才有可能. (这将进一步意味着创建线程涉及创建所有共享对象的深层副本).
现在我知道这不可能是真的,因为每个线程维护所有共享对象的完全不同的副本是非常低效的.因此,我非常怀疑.在主线程中执行"worker.value"是否引用了与在子线程中执行"this.value"不同的内存位置?子(Worker)线程会缓存"值"吗?
问候.
现在我的论点是,有可能Worker(子)线程可以在本地缓存Worker对象线程的变量"value",并在将值设置为1时更新它的副本.在这种情况下,主线程可能看不到更新的值.
你是对的.即使您正在处理相同的Worker实例,也无法保证Worker已在各种不同的线程内存缓存之间同步了字段的缓存内存版本.
value必须将该字段标记为volatile保证其他线程将看到value = 1;该value字段的更新.
但是我的队友认为,由于对"值"的访问是通过对象(worker)进行的,因此两个线程都可以看到不同的值,只有两个线程都维护"worker"对象本身的单独副本才有可能. ...
不,这不正确.线程内存的棘手部分围绕处理器内存缓存.如果没有强加的内存屏障,volatile进程可以完全自由地缓存内存.因此,即使两个线程都使用相同的实例Worker,它们也可能具有与之关联的内存的本地缓存副本Worker.
线程架构得到了很大的速度,因为它们使用独立的高速处理器本地内存,而不是始终引用中央存储.
| 归档时间: |
|
| 查看次数: |
258 次 |
| 最近记录: |