2

クラスがある場合は、それをXと呼び、Xにはコレクションが含まれます(同期されたコレクションの1つを使用しておらず、通常のコレクションを使用していると仮定します)。

独自のメソッドsyncedadd()を作成する場合、ロックはどのように機能しますか?ロックは、コレクションオブジェクトではなく、Xのインスタンスで実行されますか?

したがって、add()メソッドを同期しても、Xの多くのインスタンスがadd()を呼び出してコレクションに挿入するのを止めることはできません。したがって、スレッドの問題が発生する可能性がありますか?

4

4 に答える 4

4

同期メソッドはオブジェクトをロックします。が同期されている場合X.add、同じオブジェクトの他の同期されたメソッドの同時実行が妨げられXます。そのオブジェクトの誰かXが同じコレクションにアクセスできる場合、コレクションは保護されません。

コレクションを保護したい場合は、の同期方法以外の方法で他の場所からコレクションにアクセスできないようにしてXください。また、これはあなたの質問では少し不明確ですが、同期された非静的メソッドがオブジェクトをロックすることに注意してください。X各インスタンスが独自のコレクションを持っていると仮定すると、それらは互いに干渉しません。

別のオプション、ところで、Xオブジェクトの代わりにコレクションをロックすることです:

void add(Object o) {
   synchronized(myCollection) {
      myCollection.add(o);
   }
}

これにより、オブジェクトではなく、ロックされたコレクションへのアクセスが同期されXます。より簡単で効果的な方を使用してください。

于 2012-07-06T13:56:59.583 に答える
1

あなたの例でsynchronizedは、一度に1つのスレッドだけがクラスの1つのインスタンスでメソッドを呼び出すことができることを確認します。他の方法でそのコレクションにアクセスできますが、これは安全ではありません。スレッドセーフなコレクションの実装の詳細については、同時コレクションを検索してください。

于 2012-07-06T13:57:27.387 に答える
1

独自のメソッドsyncedadd()を作成する場合、ロックはどのように機能しますか?ロックは、コレクションオブジェクトではなく、Xのインスタンスで実行されますか?

ロックは、同期したオブジェクトで実行されます。オブジェクト内のフィールドでは実行されません。ロックが機能するには、すべてのスレッドがまったく同じオブジェクトで同期する必要があります。通常、private finalオブジェクトはロックするのが最適です。

    private final Collection<...> myCollection = ...
    ...
    synchronize (myCollection) {
        myCollection.add(...);
    }

一般的なパターンは、保護しているオブジェクトをロックすることですが、実際には任意の定数オブジェクトにすることができます。次のこともできます。

    private final Object lockObject = new Object();
    ...
    synchronize (lockObject) {
        myCollection.add(...);
    }

したがって、add()メソッドを同期しても、Xの多くのインスタンスがadd()を呼び出してコレクションに挿入するのを止めることはできません。したがって、スレッドの問題が発生する可能性がありますか?

アプリケーションの他の部分がブロック内にmyCollection なくsynchronized (myCollection)てもアクセスしている場合は、はい、スレッドの問題が発生します。コレクションを適切に保護し、メモリバリアを提供するには、すべてのアクセスを同期する必要があります。つまりadd(...)、、、contains(...)イテレータなどです。

多くの場合、コレクションまたは他のクラスを保護しようとしている場合は、同期を行うクラスでそれをラップするのが理にかなっています。synchronizedこれにより、ロックが非表示になり、ブロックが欠落しているコードからの意図しない変更からコレクションが保護されます。

于 2012-07-06T14:02:02.877 に答える
0

1つのコレクション多くのXインスタンスで共有しているというのは本当ですか?次に、コレクションインスタンス自体で同期する必要があります。メソッド自体を作成するのではなく、すべてのコードをブロックsynchronizedにラップします。synchronized(coll) { ... }

一方、各Xに独自のコレクションがある場合synchronized add()は、必要なのはそれだけです。addこれにより、2つのスレッドが同じインスタンスで同時に実行されないことが保証されます。

于 2012-07-06T14:12:03.237 に答える