Почему wait() и notify() не находятся в специальном классе?
Почему методы wait
, notify
и notifyAll
помещаются в Object
, а не в какой-то отдельный класс?
Обратите внимание: этот вопрос заключается не в том, чтобы переместить их в класс Thread
, мне просто интересно, почему они мешают Object
, а не какой-то новый класс Monitor
.
Я вижу следующие недостатки этой идеи:
- Мы не сможем использовать наши поля для других целей в качестве мониторов. Но это, похоже, согласуется с принципом модульности.
- Синхронизированные методы теперь потребуют некоторого взлома с генерируемыми скрытыми полями (например, в закрытии), поскольку
this
и <MyClass>.class
становятся недопустимыми мониторами.
Таким образом, мы могли бы отвести 5 способов от каждого объекта с небольшим горем. Или нет?
Ответы
Ответ 1
Настоящий ответ заключается в том, что это была ошибка, наконец, признанная с созданием класса Condition
, который делает именно то, d ожидаем. (Хотя, поскольку это объект, есть вероятность, что вы случайно вызовете wait()
на нем вместо await()
, с веселыми последствиями...)
Помимо того, что вы уже указали, привязка монитора к каждому отдельному объекту также делает невозможным наличие действительно неизменяемых объектов в Java.
Итак, вы можете сделать это, например:
class A {
void foo() {
synchronized((Integer)42) {
...
}
}
}
class B {
void foo() {
synchronized((Integer)42) {
...
}
}
}
Возвращение одинакового целого числа в ячейке для 42
каждый раз не должно быть проблемой, если объект неизменен. Но это не так, у него есть изменяемое состояние: его монитор, что делает такую синхронизацию возможной. Что особенно плохо в этом, так это то, что вы создали мьютекс между двумя фрагментами кода, которые на первый взгляд кажутся независимыми.
Ответ 2
Одно из преимуществ этого заключается в том, что вы можете просто синхронизировать ссылку, не создавая для нее избыточный монитор:
synchronized (myList) {
myList.add(0);
}
против
private final Object mySpecialMonitor = new Object();
syncronized(mySpecialMonitor) {
myList.add(0);
}
Это не сработает, если вся синхронизация была в отдельном классе.
Ответ 3
Потому что каждый объект может действовать как монитор.
Ответ 4
1) Ожидание и уведомление - это не просто обычные методы или утилита синхронизации, более того, они являются механизмом связи между двумя потоками в Java. Класс Object - это правильное место, чтобы сделать их доступными для каждого объекта, если этот механизм недоступен через любое ключевое слово java, например, синхронизированное. Помните, синхронизированы и ждать уведомления являются две разные области и не путать, что они такие же или связанные. Синхронизировано, чтобы обеспечить взаимное исключение и обеспечить безопасность потоков класса Java, например, состояние гонки, в то время как ожидания и уведомления являются механизмом связи между двумя потоками.
2) Блокировки доступны для каждого объекта, что является еще одной причиной ожидания и уведомления в классе Object, а не в классе Thread.
3) В Java, чтобы войти в критический раздел кода, потоки нуждаются в блокировке, и они ждут блокировки, они не знают, какие потоки хранят блокировку, вместо этого они просто знают, что блокировка удерживается каким-то потоком, и они должны ждать вместо того, чтобы знать, какой поток находится внутри синхронизированного блока, и попросить их освободить блокировку. эта аналогия подходит с ожиданием и уведомляет об объектном классе, а не о потоке в Java.
с ссылкой: http://javarevisited.blogspot.in/2012/02/why-wait-notify-and-notifyall-is.html