0

いくつかの簡単な検索の後、明確な答えを見つけることができませんでした。

クラス全体で(インスタンスにバインドされた)メンバーメソッド全体を同期するよりエレガントな方法はありますか? つまり、メソッドは複数のインスタンスで複数のスレッドから呼び出すことができますが、一度に 1 つのスレッドからのみ呼び出すことができます。同期ブロックとしても記述できます。

(説明のために、メソッドはそのインスタンスを共有キャッシュに挿入します。)

class DataObject {

  public putInCache() {
    synchronized(getClass()) {

      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff

    }
  }

}
4

3 に答える 3

6

パブリックにアクセス可能なオブジェクトでの同期を避けることをお勧めします。ただし、共有モニター オブジェクトを使用することはできます。

class DataObject {

  private static final Object cacheLock = new Object();

  public putInCache() {
    synchronized(cacheLock) {

      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff

    }
  }
}

この特定の実装DataObjectでは、それから派生したすべてのクラスがロックを共有することに注意してください。

于 2013-02-21T13:00:12.697 に答える
5

Classと同期には違いがありinstanceます。
インスタンスの同期は の各インスタンスで機能するObjectため、コードは次のようになります。

  public synchronized void putInCache() {
      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff
  }

そしてコード

  public void putInCache() {
    synchronized(this) {
      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff
    }
  }

複数のスレッドが同時に同期ブロックに入ることを許可しないという点で同等です。ただし、これはクラスの各インスタンスのみです。つまり、モニターはオンですthis

クラス同期はClassそれ自体で機能し、次の 2 つのブロックも同等です。

  public static synchronized void putInCache() {
      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff
  }
  public void putInCache() {
    synchronized(MyClass.class) {
      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff
    }
  }

JVM 全体で複数のスレッドが同期ブロックに同時に入ることはまったく許可されません。つまり、モニターはClassインスタンス上にあり、一意です。

Class同期を使用する必要があります。

別の方法は、同時アクセスを防止しようとしているリソース自体をロックすることです。リソースをnullにすることはできず、リソースのインスタンスがランダムに変更されない場合-finalこれを行うことができればさらに良いです:

 public void putInCache() {
    synchronized(cache) {
      // ... do some stuff
      cache.insert(this);
      // ... do some more stuff
    }
  }

これにより、ロックしている理由とロックしているものが非常に明確になります。

于 2013-02-21T13:04:33.380 に答える
0

クラスレベルの同期を探していると思います。メソッドを静的で同期されたものにしてみてください。例えば:

public synchronized static putInCache(){
//..your code
}

これは、「メソッドは複数のスレッドによって複数のインスタンスで呼び出すことができますが、一度に 1 つのスレッドによってのみ呼び出すことができる」ことを意味します。

于 2013-02-21T13:22:29.193 に答える