0

Java で同期キーワードを使用したロックがどのように機能するかを理解しようとしています。クラスがある場合(パブリック変数などを使用した悪い習慣などは忘れてください)

class Person 
{
    public int money;
    public String name;

    public void give_bonus()
    {
        synchronize(this)
        {
            money += 10;
            name = "....";
        }
    }
}

// thread one 
person.give_bonus();

// thread two
person.money += 50;

ここで私の質問は、インスタンス ロック (これ) を使用してロック ブロックを作成すると、他のスレッドがプロパティ money を操作できなくなるのでしょうか? または、money プロパティを非公開にし、同期修飾子を使用して getter / setter を定義して、この値が競合状態に陥る危険性がないことを確認する必要がありますか?

4

3 に答える 3

2

あなたが提供するコードは、メソッドが戻るまで (または、メソッドが戻る直前に)、 他のスレッドがメソッドmoneyを介して変数を変更するのを防ぐだけです。give_bonus()

ご想像のとおり、安全のために変数を作成privateし、setter メソッドに同期を追加する必要があります。同じロックで同期していることを確認してください。

于 2013-05-26T19:10:19.477 に答える
1

同期は、オブジェクトthisの内容とはまったく関係ありません。thisJava のロック メカニズムは、基本的に、「オブジェクト性」とはまったく別の役割を果たしている通常のオブジェクトに便乗しています。このもう 1 つのロールには、各オブジェクトのmonitorと呼ばれる特別なフィールドが含まれ、どのスレッドがそれを何回取得したかを記録します。

于 2013-05-26T19:26:28.497 に答える
0

各オブジェクト インスタンスが 1 つの「チケット」(そのモニターと呼ばれる) を所有しているかのように考えることができます。スレッドが特定のオブジェクトにあるブロックに入りたい場合、スレッドsynchronizedは最初にオブジェクトから「チケットを取得」する必要があり、ブロックを終了するか、ブロックを呼び出すwait()ときにチケットを返します。

チケットが現在利用できない場合 (同じチケットを必要とする同じブロックまたは別の同期ブロックに別のスレッドがあるため)、待機する必要があります。

あなたの例では、スレッド 2 が直接アクセスするのを止めるものは何もありません。moneyスレッド 1 が同期ブロックにあるという事実は、スレッド 2 が同じモニターで同時に同期ブロックに入ることを止めるだけです。

于 2013-05-26T19:20:51.553 に答える