2015-09-12 3 views
5

Если вы посмотрите документацию, описывающую использование переменных условия (cv), вы увидите, что, например, в PThreads и C++ вам не нужно удерживать мьютекс cv, чтобы вызывать уведомление об этом cv. В то время как, например, в Java и Python вы должны заблокировать мьютекс, чтобы сделать то же самое.Шаблон использования переменных условий в языках C/C++ и других языках

Есть ли какая-то серьезная причина, почему вещи реализованы таким образом (я имею в виду последний случай), учитывая, что реализация языка, такого как Java, в конечном итоге использует некоторые собственные инструменты потоковой передачи?

+0

Возможно, это не реализовано поверх просто pthreads .. но это всего лишь предположение. Я чувствую, что этот вопрос может стать лучше (или даже * any *) ответов на http://cs.stackexchange.com/ ... –

+0

Очевидно, что JVM может реализовать его так, но это делает распространенную ошибку, которую я видел многие, многие люди делают на C++ гораздо менее вероятно при достаточно низкой стоимости (вам нужно удерживать блокировку немного дольше, но это все) – Voo

+0

@Voo Ошибка в том, что мьютекс не удерживается при изменении данных, от которых зависит условие? – vehsakul

ответ

0

В базовых инструментах синхронизации Java notify и notifyAll требуется синхронизировать объекты перед их вызовом. Это для простой точки безопасности, так как это также требует, чтобы вы синхронизировали их до wait ing.

Например, если у вас есть два потока. Один поток считывает данные из буфера, а один поток записывает данные в буфер.

Поток данных для чтения должен ждать, пока поток данных записи завершит запись блока данных в буфер, а затем он сможет прочитать блок.

Если wait(), notify() и notifyAll() методы могут быть вызваны без синхронизации, то вы можете получить состояние гонки, где:

  • Показание поток вызывает wait() и поток добавляется в очередь ожидания.

  • В то же время, поток письма вызывает notify(), чтобы сигнализировать, что он добавил данные.

  • Читающая нить пропускает изменение и ждет навсегда, так как notify() был обработан до wait().

Заставляя wait и notify произойти в пределах синхронизированного блока это условие гонки удаляется.