dev*_*ull 4 java multithreading
我发现了这句话:
在正确构造的对象中,无论对象如何发布,所有线程都将看到最终字段的正确值.
那么为什么使用volatile变量来安全地发布Immutable对象呢?
我真的很困惑.任何人都可以通过一个合适的例子说清楚吗?
在这种情况下,波动性只会确保新对象的可见性; 根据JSR-133的初始化安全保证,碰巧通过非易失性字段获取对象的任何其他线程确实会看到最终字段的正确值.
尽管如此,使变量不变不会受到伤害; 从内存管理的角度看是正确的; 和将有必要在构造函数初始化(虽然不应该有任何这些不可变的对象)非最终字段.如果您希望在线程之间共享变量,则需要确保足够的同步以提供可见性 ; 虽然在这种情况下你是对的,但构造函数的原子性没有危险.
感谢Tom Hawtin指出我完全忽视了JMM对最终领域的保证; 之前的错误答案如下.
volatile变量的原因是在对象的构造和变量的赋值之间建立了一个先发生关系(根据Java Memory Model).这实现了两件事:
由于不可变对象的基本规则之一是您在构造函数期间不发布引用,因此这可能是第二点.在没有适当的并发处理多线程环境中,它是可能的对象的引用,是"发表"该对象已建成之前.因此,另一个线程可以获取该对象,看到它的一个字段是null,然后看到这个"不可变"对象已经改变.
请注意,如果您有其他适当的同步原语,则不必使用volatile字段来实现此目的 - 例如,如果分配(以及所有后续读取)在synchronized给定监视器上的块中完成- 但是在"独立"中感觉,标记变量volatile是告诉JVM"这可能被多个线程读取的最简单方法,请在该上下文中安全地进行分配".
| 归档时间: |
|
| 查看次数: |
1585 次 |
| 最近记录: |