英文:
Java 'final' instance variable - visibility and propagation of variable's internal state
问题
在阅读与线程和锁有关的文档时,有一句描述final
关键字的句子引起了我的注意:
> 相应地,编译器允许将final字段的值保留在寄存器中,而不是在需要重新加载非final字段的情况下从内存中重新加载它。
这是否意味着,如果我将final Object object = ...
声明为实例变量,然后从匿名内部类(多个Runnable
实例)中访问它(修改其内部状态 - object.state
),那么object.state
的值实际上可以从/写入到CPU缓存中,并且它(object.state
的值)可能在这些Runnable
实例之间不同步?
因此,如果我想确保object.state
的值在所有线程之间正确传播,我必须将object
声明为volatile Object object
,是吗?
谢谢。
编辑:我已编辑了原始问题。现在我知道我误解了文档,所以对于我最后的问题,答案是不是 - volatile/final Object object
对object.state
没有影响 - 它取决于如何声明、初始化和/或访问object.state
。
感谢@Burak Serdar的答复!
英文:
While reading the documentation related to Threads and Locks, a sentence describing final
keyword attracted me:
> Correspondingly, compilers are allowed to keep the value of a final field cached in a register and not reload it from memory in situations where a non-final field would have to be reloaded.
Does it mean, that if I declare a final Object object = ...
as an instance variable and then access it (modify its inner state - object.state
) from anonymous inner classes (multiple instances of Runnable
), then the value of object.state
could actually be read/written from/into CPU cache and it (value of object.state
) could be out of sync across those Runnable
instances?
So if I want to be sure, that the value of object.state
is properly propagated across all the threads I have to declare the object
as volatile Object object
instead?
Thank you.
Edit: I have edited my original question. And now I know I misunderstood the documentation so the answer to my last question is NO - volatile/final Object object
has no effect on object.state
- it depends how the object.state
is declared, initialized and/or accessed.
Thanks to the @Burak Serdar for the answer!
答案1
得分: 3
当您声明 final Object object = ...
时,最终的值是指向该对象的引用,而不是对象的内部状态。这意味着任何内容都不能修改 object
本身,但这并不意味着不能修改例如 object.value
这样的内容。因此,变量 object
可能会被缓存,但这并不意味着可以缓存 object
的内部状态。
英文:
When you declare a final Object object=...
, the final value is the reference to the object, not the internal state of the object. It means than nothing can modify object
, it does not say that nothing can modify, say, object.value
. So the variable object
can be cached, which does not mean the internal state of object
can be cached.
答案2
得分: -1
以下是翻译好的内容:
Final 不会像你希望的那样帮助你解决线程问题,抱歉。
在某些情况下,Volatile 可能会有所帮助,但你可能需要使用锁。
来自 Oracle 教程:
-对于引用变量和大多数原始变量(除了 long 和 double 类型),读取和写入是原子的。
-对于所有声明为 volatile 的变量(包括 long 和 double 变量),读取和写入都是原子的。
这意味着在读取和写入之间,你的对象不会立即更新,但在一个读取/写入内部是一致的。
英文:
Final will not help you with threading issues the way you hope, sorry.
Volatile may help in some situations, but you may need a lock.
From the Oracle tutorials:
-Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
-Reads and writes are atomic for all variables declared volatile (including long and double variables).
That means your object will not be immediately updated between reads and writes, but it will be consistent within one read/write.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论