1

void私はJavaに関する本を読んでいました.1つのプライベート変数、プライベート変数を計算して設定するための高価な操作を行う1つのパブリックメソッド、およびプライベート変数を返す2番目のパブリックメソッドを持つクラスを宣言するこの演習問題がありました変数。質問は「どうすればこのスレッドセーフにできるか」であり、考えられる答えの 1 つは「2 つのメソッドをそれぞれ同期する」であり、もう 1 つの考えられる答えは「このクラスをスレッドセーフにすることはできない」でした。

両方のメソッドを同期したとしても、Thread1 がセッターを呼び出し、Thread1 がゲッターを呼び出す前に、Thread2 が実行されてセッターを呼び出す可能性があるため、クラスをスレッドセーフにすることはできないと考えました。行って結果を取得すると、間違った情報が得られます。これは物事を見る正しい方法ですか?この本は、2 つのメソッドを同期させることでクラスをスレッドセーフにすることが正しい答えであると示唆していましたが、今では混乱しています...

4

3 に答える 3

3

両方のメソッドを同期したとしても、Thread1 がセッターを呼び出し、Thread1 がゲッターを呼び出す前に、Thread2 が実行されてセッターを呼び出す可能性があるため、クラスをスレッドセーフにすることはできないと考えました。行って結果を取得すると、間違った情報が得られます。これは物事を見る正しい方法ですか?

あなたはこれで正しいです。class 内から、各メソッドの呼び出しの間に、スレッドがいずれのメソッドも呼び出していないことを保証する方法はありません。

これを行う場合は、ラッパー クラスが必要になります。したがって、ゲッターとセッターを持つクラスが次のような場合:

class Foo
{
    private static int bar;

    public static synchronized void SetBar(int z) { ... }
    public static synchronized int GetBar() { ... }
}

ラッパー クラスは次のようになります。

class FooWrapper
{

    public synchronized int SetGetBar(int z)
    {
        Foo.SetBar(z);
        return Foo.GetBar();
    }

}

これが機能することを保証する唯一の方法は、すべての呼び出しがクラス Foo に直接ではなく、ラッパー クラスを経由することを保証できる場合です。

于 2013-08-23T02:19:43.347 に答える