This question already has answers here:
Why can an Object member variable not be both final and volatile in Java?

(7个答案)


7年前关闭。




我想理解为什么为什么声明为final的引用不能声明为Volatile。关于SO [Why can an Object member variable not be both final and volatile in Java?

[1]:Why can an Object member variable not be both final and volatile in Java?,但我不确定该答案是否理解了FINAL。

现在,最终变量的状态可以在初始化后确定地更改。只有引用不能初始化为另一个对象。

例如考虑以下成员变量
final StringBuilder sb = new StringBuilder("CAT");

现在另一个线程将sb更改为:
sb.append("S");

如果此变量为Non-Volatile,根据Java内存模型,此更改是否可用于不同的线程?

编辑:我将StringBuffer更改为StringBuilder,以使某些人明白我的观点。

最佳答案



是的,但是那是因为StringBuffer是线程安全的-意味着它在内部提供锁定,这将导致内存障碍,因此其他线程可以查看更新。

可变的引用不会影响对象上的操作,而是会影响引用。

所以你可以做

 volatile StringBuilder b = new StringBuilder();

 b = someOtherStringBuilder;

现在,由于b是volatile,其他线程将看到此引用的更新。

但是做
 b.append("foo");

无法保证其他线程会看到对现有b对象的更改。与StringBuffer不同,StringBuilder不是线程安全的,因此无论如何都不要提供自己的锁定,否则不要这样做。

如果您想保证b.append("foo");对其他线程可见而没有任何锁定,则StringBuilder中的每个成员字段也需要是可变的。 (尽管这不能使其线程安全)

09-10 06:15
查看更多