Почему 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