Когда вы выполняете
sa = new String("Done");
, вы не изменяете содержимое ссылок String на sa
.Вы присваиваете новый экземпляр String (новый объект) sa
.Строки неизменны.Невозможно изменить их значение.
Это означает, что вы синхронизируете по sa (первый объект: «Not Done»), затем назначаете новый объект для sa (второй объект: «Done») и вызываете notifyэто второй объект.Поскольку вы синхронизировались не со вторым объектом, а с первым, вы получаете исключение IllegalMonitorException.Вызов notify для объекта разрешен только в том случае, если вы владеете встроенной блокировкой объекта.Вот почему блокировка всегда должна быть окончательной.
Вызов notify () эквивалентен вызову this.notify ().Так что this.notify()
и sa.notify()
просто вызывают notify()
для двух разных объектов.Первый уведомит поток, ожидающий на this
, а второй уведомит поток, ожидающий на sa
.
Тот факт, что переменная является статической или нет, не имеет значения.Блокировка связана с объектом, а не с его ссылкой.