web-dev-qa-db-ja.com

クラスのすべてのインスタンス間でメソッドを同期させる方法

今日、私はこのインタビューの質問をされました、そして答えることができませんでした。同期されるsetAddressメソッドを持つPersonクラスの2つのインスタンスがある場合。オブジェクトが1つだけで、複数のスレッドがそのオブジェクトにアクセスしている場合、synchronizedは、一度に1つのメソッドだけがアクセスできるようにします。

ただし、異なるオブジェクトがある場合、メソッドに入る前に1つのスレッドが他のスレッドを待機しません。

ここで問題は... Personオブジェクトのすべてのインスタンス間でメソッドを同期させる場合、どうすればよいですか?

6
Kaushik

Person.classで同期するか、同期する静的LOCKオブジェクトを作成します。

synchronize(Person.class){
    //...
}

または

private static final Object LOCK = new Object();

//...
synchronize(LOCK){
    //...
}

どちらの方法でも、すべての呼び出し元に共通の単一の(静的)ロックオブジェクトインスタンスを使用しています。クラスでの同期は、同期されたstaticメソッドのデフォルトの動作を反映します。しかし、それはロックをいくらか公開します。たとえば、いくつかの邪悪なコードがPerson.classそしてロックを解除しないでください。コードを詰まらせてください。したがって、個別のプライベートロックを保持する方が安全です。

12
ratchet freak

同期して、setAddress()メソッドを静的にします。基本的に、setAddress()メソッドをグローバルにして、このメソッドのコピーが1つだけ存在するようにし、同期させることにより、このメソッドに入るスレッドは1つだけになります。

パブリック同期静的void setAddress(){// ...}

欠点があります。すべてのインスタンス変数を静的にする必要があります。静的メソッドから静的変数にのみアクセスできるため。

0
Prashant K S