Синхронизированный блок Java для .class - PullRequest
94 голосов
/ 13 января 2010

Что означает этот код Java? Получит ли он блокировку на всех объектах MyClass?

synchronized(MyClass.class) {
   //is all objects of MyClass are thread-safe now ??
}

И чем вышеуказанный код отличается от этого:

synchronized(this) {
   //is all objects of MyClass are thread-safe now ??
}

Ответы [ 3 ]

135 голосов
/ 13 января 2010

Фрагмент synchronized(X.class) использует экземпляр класса в качестве монитора. Поскольку существует только один экземпляр класса (объект, представляющий метаданные класса во время выполнения), в этом блоке может находиться один поток.

При synchronized(this) блок охраняется экземпляром. Для каждого экземпляра только один поток может войти в блок.

synchronized(X.class) используется, чтобы убедиться, что в блоке ровно одна нить. synchronized(this) гарантирует, что для каждого экземпляра существует ровно один поток. Если это делает фактический код в блоке потокобезопасным, зависит от реализации. Если изменить только состояние экземпляра synchronized(this) достаточно.

77 голосов
/ 13 января 2010

Чтобы добавить к другим ответам:

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}

эквивалентно

static synchronized void myMethod() {
  //code
}

и

void myMethod() {
  synchronized(this) {
    //code
  }
}

эквивалентно

synchronized void myMethod() {
  //code
}
21 голосов
/ 13 января 2010

Нет, первый получит блокировку определения класса MyClass, а не всех его экземпляров. Однако, если он используется в экземпляре, это фактически блокирует все остальные экземпляры, так как они совместно используют одно определение класса.

Второй получит блокировку только для текущего экземпляра.

Относительно того, делает ли это ваши объекты безопасными для потоков, это гораздо более сложный вопрос - нам нужно увидеть ваш код!

...