del tipo Integer
o similar? --
reemplaza el objeto inmutable Integer
con otro. Por lo tanto, está llamando al notify
en un objeto diferente al synchronized
.
Su código es el equivalente a:
Integer syncConunt = Integer.valueOf(5);
[...]
synchronized (syncCount) {
syncCount = Integer.valueOf(syncCount.intValue() + 1);
syncCount.notify();
}
Usted no está solo. Incluso antes de J2SE 5.0, he visto código de ejemplo publicado en un libro que asignó una referencia dentro de un bloque sincronizado. En general, es una buena idea marcar los campos de bloqueo final
.
Otro punto importante es que el código se sincroniza en un objeto que no "posee". Integer
se comparten los objetos (Integer.valueOf(int)
devolverá exactamente la misma instancia si se llama con valores entre -128 y 127, y tal vez más). Si esto fuera hecho por dos piezas de código no relacionado, entonces habría interacciones ocultas. Esto se aplica a cualquier tipo en el que las instancias se compartan entre código no relacionado. Los ejemplos comunes son Integer
, String
, Class
(utilizado por métodos estáticos sincronizados) y Thread
(en la implementación de Sun, Thread
pasa a usarse como cerradura para join
).
Muchas gracias. Esto resuelve el problema. –
Puede resolver la excepción lanzada, pero debe comprender lo que dice Tom al declarar el campo final. No es seguro declarar un nuevo objeto en su propio bloque sincronizado –
gran error de concurrencia. –