Почему Java и C # добавили встроенную блокировку к каждому объекту?
Создание каждого блокируемого объекта выглядит как ошибка проекта:
You add extra cost for every object created, even though you'll actually use it only in a tiny fraction of the objects. Lock usage become implicit, havinglockMap.get(key).lock()
is more readable than synchronization on arbitrary objects, eg, synchronize (key) {...}
.
Synchronized methods can cause subtle error of users locking the object with the synchronized methods
You can be sure that when passing an object to a 3rd parting API, it's lock is not being used.
например
class Syncer {
synchronized void foo(){}
}
...
Syncer s = new Syncer();
synchronize(s) {
...
}
// in another thread
s.foo() // oops, waiting for previous section, deadlocks potential
Not to mention the namespace polution for each and every object (in C# at least the methods are static, in Java synchronization primitives have to use await
, not to overload wait
in Object
...)
Однако я уверен, что есть какая-то причина для этого дизайна. В чем великое преимущество встроенных замков?