Почему Java и С# добавили внутреннюю блокировку для каждого объекта?

Заблокирование каждого объекта выглядит как ошибка дизайна:

  • Вы добавляете дополнительную стоимость для каждого созданного объекта, даже если вы фактически используете его только в небольшой части объектов.
  • Использование блокировки становится неявным, а lockMap.get(key).lock() более читабельным, чем синхронизация на произвольных объектах, например synchronize (key) {...}.
  • Синхронизированные методы могут вызывать тонкую ошибку пользователей, блокирующих объект с помощью синхронизированных методов.
  • Вы можете быть уверены, что при передаче объекта в третий API-интерфейс parting блокировка не используется.

например,

class Syncer {
    synchronized void foo(){}
}
...
Syncer s = new Syncer();
synchronize(s) {
    ...
}
// in another thread
s.foo() // oops, waiting for previous section, deadlocks potential
  • Не говоря уже о разрешении пространства имен для каждого объекта (в С#, по крайней мере, методы статичны, в примитивах синхронизации Java необходимо использовать await, а не перегружать wait в Object...)

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

Ответы

Ответ 1

На самом деле у вас есть только ссылка на этот монитор в каждом объекте; реальный объект монитора создается только при использовании синхронизации = > не столько память потеряна.

Альтернативой было бы добавить ручной монитор для тех классов, которые вам нужны; это очень усложнит код и будет более подверженным ошибкам. Java продает производительность для производительности.

Ответ 2

Одним преимуществом является автоматическая разблокировка при выходе из блока synchronized, даже по исключению.

Ответ 3

Я предполагаю, что, как и toString(), дизайнеры полагали, что выгоды повышают стоимость.

Необходимо было принять множество решений, и многие из них были непроверены (проверенные исключения - ack!), но в целом я уверен, что он в значительной степени свободен и полезен, чем явный объект "Lock".

Также вы добавляете объект "Lock" к языку или библиотеке? Похоже, что это языковая конструкция, но объекты в библиотеке очень редко (если вообще когда-либо?) Имеют специальное лечение, но обработка потоков в большей мере, поскольку библиотека может замедлить работу.