Синхронизированный блок Java для.class

Что означает этот код 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 ответа

Решение

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

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

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

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

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

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

static synchronized void myMethod() {
  //code
}

а также

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

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

synchronized void myMethod() {
  //code
}

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

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

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

Да, будет (для любого синхронизированного блока / функции).

Я думал над этим вопросом пару дней для себя (на самом деле в котлине). Я наконец нашел хорошее объяснение и хочу им поделиться:

Блокировка на уровне класса предотвращает вход нескольких потоков в синхронизированный блок в любом из всех доступных экземпляров класса во время выполнения. Это означает, что если во время выполнения имеется 100 экземпляров DemoClass, то только один поток сможет выполнять demoMethod() в любом из экземпляров за раз, а все остальные экземпляры будут заблокированы для других потоков.

Блокировка уровня класса всегда должна выполняться, чтобы сделать статические данные потокобезопасными. Как мы знаем, ключевое слово static связывает данные методов с уровнем класса, поэтому используйте блокировку статических полей или методов, чтобы сделать это на уровне класса.

Плюс заметить, почему .class. Это просто потому, что.class эквивалентен любой статической переменной класса, подобного:

private final static Object lock = new Object();

где имя переменной блокировки - это класс, а тип - Class

Подробнее:https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/

Другие вопросы по тегам