Что означает этот код 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 ??
}
java
multithreading
synchronization
locking
synchronized
Андрей Тобилко
источник
источник
Ответы:
Фрагмент
synchronized(X.class)
использует экземпляр класса в качестве монитора. Поскольку существует только один экземпляр класса (объект, представляющий метаданные класса во время выполнения), в этом блоке может находиться один поток.С
synchronized(this)
блоком охраняется экземпляр. Для каждого экземпляра в блок может войти только один поток.synchronized(X.class)
используется, чтобы убедиться, что в блоке ровно один поток.synchronized(this)
гарантирует, что для каждого экземпляра будет ровно один поток. Если это делает фактический код в блоке потокобезопасным, это зависит от реализации. Если мутировать, достаточно только состояния экземпляраsynchronized(this)
.источник
Чтобы добавить к другим ответам:
эквивалентно
и
эквивалентно
источник
synchronized
блоков. Это делает их эквивалентными. Если вы измените один пример, они действительно уже не те.Нет, первый получит блокировку определения класса
MyClass
, а не всех его экземпляров. Однако при использовании в экземпляре это эффективно заблокирует все другие экземпляры, поскольку они используют одно определение класса.Второй получит блокировку только для текущего экземпляра.
Что касается того, делает ли это ваши объекты потокобезопасными, это гораздо более сложный вопрос - нам нужно увидеть ваш код!
источник
Да, будет (для любого синхронизированного блока / функции).
Я думал над этим вопросом пару дней для себя (на самом деле в котлине). Я наконец нашел хорошее объяснение и хочу им поделиться:
Блокировка уровня класса предотвращает вход нескольких потоков в синхронизированный блок в любом из всех доступных экземпляров класса во время выполнения. Это означает, что если во время выполнения имеется 100 экземпляров DemoClass, то только один поток сможет выполнять demoMethod () в любом из экземпляров за раз, а все остальные экземпляры будут заблокированы для других потоков.
Блокировка уровня класса всегда должна выполняться, чтобы сделать статические данные потокобезопасными. Как мы знаем, ключевое слово static связывает данные методов с уровнем класса, поэтому используйте блокировку статических полей или методов, чтобы сделать это на уровне класса.
Плюс заметить, почему .class . Это просто потому, что
.class
это эквивалентно любой статической переменной класса, подобного:где имя переменной блокировки - это класс, а тип - Class <T>
Подробнее: https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/
источник