成员方法在全班同步

时间:2013-02-21 12:56:17

标签: java synchronized

经过一番快速搜索,我无法找到明确的答案。

有没有更优雅的方法来同步整个类的整个成员方法(绑定在实例上)?这意味着可以通过多个线程在多个实例上调用方法,但是当时只能由一个线程调用。它也可以写成同步块。

(例如,该方法将其实例插入共享缓存中。)

class DataObject {

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

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

    }
  }

}

3 个答案:

答案 0 :(得分: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并从其派生的所有类将共享锁。

答案 1 :(得分:5)

Classinstance同步之间存在差异 实例同步适用于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本身,以下两个块也是等效的:

  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
    }
  }

这清楚地说明了为什么要锁定以及锁定什么。

答案 2 :(得分:0)

我猜你正在寻找班级同步。尝试使该方法成为静态和同步的方法。 例如:

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

这意味着“可以通过多个线程在多个实例上调用方法,但当时只能由一个线程调用。”