Ответ 1
Тип Integer
или аналогичный? --
заменяет неизменяемый объект Integer
на другой. Поэтому вы вызываете notify
на другой объект, чем synchronized
.
Ваш код эквивалентен:
Integer syncConunt = Integer.valueOf(5);
[...]
synchronized (syncCount) {
syncCount = Integer.valueOf(syncCount.intValue() + 1);
syncCount.notify();
}
Ты не одинок. Еще до J2SE 5.0 я видел пример кода, опубликованного в книге, которая назначила ссылку в синхронизированном блоке. В общем, рекомендуется отметить поля блокировки final
.
Еще один важный момент - синхронизация кода на объекте, который он не "владеет". Integer
объекты разделяются (Integer.valueOf(int)
будет возвращать точно тот же экземпляр, если он вызван со значениями между -128 и 127 и, возможно, дополнительно). Если бы это было сделано двумя частями несвязанного кода, тогда были бы скрытые взаимодействия. Это относится к любому типу, в котором экземпляры разделяются между несвязанным кодом. Общие примеры: Integer
, String
, Class
(используется статически синхронизированными методами) и Thread
(в реализации Sun Thread
используется как блокировка для join
).