¿Por qué Java y C # agregaron bloqueo intrínseco a cada objeto?

Hacer que cada objeto se pueda bloquear parece un error de diseño:

Agrega un costo adicional por cada objeto creado, aunque en realidad solo lo usará en una pequeña fracción de los objetos.El uso del bloqueo se vuelve implícito, habiendolockMap.get(key).lock() es más legible que la sincronización en objetos arbitrarios, por ejemplo,synchronize (key) {...}.Los métodos sincronizados pueden causar un error sutil de usuarios que bloquean el objeto con los métodos sincronizadosPuede estar seguro de que al pasar un objeto a una tercera API de partición, no se está utilizando el bloqueo.

p.ej

class Syncer {
    synchronized void foo(){}
}
...
Syncer s = new Syncer();
synchronize(s) {
    ...
}
// in another thread
s.foo() // oops, waiting for previous section, deadlocks potential
Sin mencionar la contaminación del espacio de nombres para cada objeto (en C # al menos los métodos son estáticos, en Java, las primitivas de sincronización deben usarseawaitno sobrecargarwait enObject...)

Sin embargo, estoy seguro de que hay alguna razón para este diseño. ¿Cuál es el gran beneficio de los bloqueos intrínsecos?

Respuestas a la pregunta(4)

Su respuesta a la pregunta