17

非プリミティブにも volatile キーワードを使用する必要があるかどうかはわかりません。あるスレッドによって設定/割り当てられ、別のスレッドによってアクセスされるクラスメンバーがあります。このメンバーを volatile と宣言する必要がありますか?

private /* volatile */ Object o;

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

public Object getMember() {
    return o;
}

ここでは、setMember(...) が 1 つのスレッドによって呼び出され、getMember() が別のスレッドによって呼び出されます。

たとえば、ブール値の場合、答えは「はい」になります。

私は Java 1.4 を使用しており、この場合のメンバーは読み取り専用です。したがって、この場合は可視性のみを気にしているので、volatile キーワードについて質問します。

4

4 に答える 4

11

はい -volatileプリミティブ型フィールドの場合とまったく同じ意味を参照型フィールドに持ちます。参照型の場合を除いて、フィールドが参照するオブジェクトのメンバーマルチスレッド アクセス用に設計する必要があります。

于 2012-05-15T20:19:28.337 に答える
8

できますし、役立つかもしれませんが、キーワードは参照の設定にのみ適用されることを覚えておいてください。そのオブジェクト内のプロパティのマルチスレッド可視性には影響しません。それがステートフルである場合、望ましい先行発生関係を確保するために、アクセスごとに同期する必要があります。

于 2012-05-15T20:19:14.443 に答える
4

はい、あなたのコードは正しいです。この場合、参照自体は揮発性であるため、参照へのチャンスは他のすべてのスレッドで自動的に表示されますが、参照されているオブジェクトへの変更はありません。

于 2012-05-15T20:19:39.367 に答える
1

クラスを調べると、としてAtomicInteger宣言されているため、スレッド キャッシュの問題なしにマルチスレッド環境で使用できます。valuevolatile

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 オブジェクトで変更されます。次に、その参照にも volatile が必要です。

private volatile AtomicInteger reference = new AtomicInteger(0);

ほとんどの場合、そうではありません。オブジェクトの値のみが変更されます。したがって、それを最終的なものとして宣言します。

private final AtomicInteger reference = new AtomicInteger(0);
于 2014-06-17T07:36:59.050 に答える