java - volatile关键字也适用于非基元

时间:2012-05-15 20:16:24

标签: java volatile

我不确定volatile关键字是否也应该用于非基元。我有一个由一个线程设置/分配的类成员,并由另一个线程访问。我应该宣布这个成员是不稳定的?

private /* volatile */ Object o;

public void setMember(Object o) {
    this.o = o;
}

public Object getMember() {
    return o;
}

这里,setMember(...)由一个线程调用,getMember()由另一个线程调用。

如果它是布尔值,例如,答案是肯定的。

我使用的是Java 1.4,本例中的成员是只读的。所以我只关心这种情况下的可见性,因此关于volatile关键字的问题。

4 个答案:

答案 0 :(得分:11)

是 - volatile对于基本类型字段的引用类型字段具有完全相同的意义。除了在引用类型的情况下,字段引用的对象的成员必须被设计用于多线程访问。

答案 1 :(得分:8)

您可以,它可能会有所帮助,但请记住该关键字仅适用于参考设置。它对该对象内部属性的多线程可见性没有影响。如果它是有状态的,你可能想要同步每次访问它,以确保所需的事先发生的关系。

答案 2 :(得分:4)

是的,您的代码是正确的。在这种情况下,引用本身是易失性的,因此引用的机会在所有其他线程中自动可见,但不会更改被引用的对象。

答案 3 :(得分:1)

如果我们查找AtomicInteger类,它已将value声明为 volatile ,因此它可用于多线程环境而无需任何线程缓存问题。

public class AtomicInteger {
    private volatile int value;

    /**
     * Gets the current value.
     *
     * @return the current value
     */
    public final int get() {
        return value;
    }

    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(int newValue) {
        value = newValue;
    }

}

但是如果你认为对AtomicInteger的引用,它将被许多线程用不同的AtomicInteger对象修改它。那么你也需要挥发性的那个参考。

private volatile AtomicInteger reference = new AtomicInteger(0);

大多数情况并非如此;只有对象的值会改变;因此宣布它为最终版。

private final AtomicInteger reference = new AtomicInteger(0);