2016-02-25 4 views
4

Я использую анализатор исходного кода, который указал, что notifyAll() не следует вызывать в экземпляре Thread. Я пытаюсь сформулировать это для руководства, но я не могу придумать объяснения. Кто-нибудь может мне помочь??Почему не может notifyAll() использоваться в экземпляре Thread?

BTW, это унаследованный код, поэтому я не несу ответственности за дизайнерское решение!

+2

Какой анализатор исходного кода указал на это? – Ferrybig

+0

Инструмент SONAR. – user1660256

+0

Что вы подразумеваете под «внутри экземпляра Thread»? Есть ли что-то действительно неправильное в том, как код вызывает 'notifyAll'? –

ответ

7

Это походит на сообщение SONAR вы видите это this one:

методы "ожидание (...)", "уведомлять()" и "notifyAll()" никогда не должен быть вызван на тему экземпляры кальмара: S2236

Sonar имеет подробное объяснение этого:

на экземпляре темы, методы ждать (...), Notify() и notifyAll() являются availabl e только потому, что все классы в Java расширяют Object и поэтому автоматически наследуют методы. Но есть две очень серьезные причины не вызывать эти методы в экземпляре Thread:

Выполнение этого действительно сбивает с толку. Что действительно ожидается при вызове, например, метода wait (...) в потоке? Что приостановление выполнения нити приостановлено или что ожидается получение объекта мониторинга объекта?

Внутри JVM использует эти методы для изменения состояния потока (BLOCKED, WAITING, ...), поэтому их вызов может повредить поведение JVM.

Аналогично, advice given in the Java API является:

Рекомендуется, чтобы приложения не используют ждать, извещать или notifyAll о случаях темы.

Управление внутренней резьбой осуществляется путем блокировки объектов резьбы. Если ваш собственный код приложения блокируется в потоках, вы можете получить неожиданное или запутанное поведение. Например, когда поток завершается, он отправляет уведомление каждому потоку, ожидающему его.

При попытке оценить потенциальные проблемы я бы искал случаи, когда поток мог получать уведомление по ошибке или пропускать уведомление из-за использования в качестве блокировки для кода приложения и как блокировки для внутренней JVM код. (Кажется, это может быть утомительным.) В зависимости от кода я также искал бы проблемы с согласованностью из-за блокировки потоков, а не для блокирования структур данных, к которым обращаются потоки, и оценивать, имеет ли смысл схема блокировки. Если код является подклассом Thread, я бы хотел проверить, запущены ли потоки и как.

В основном это сообщение заставило бы меня подумать, если этот код делает это плохо, а что еще это может сделать неправильно? Сообщение SONAR - это всего лишь намек на то, что он нашел плохой запах кода, чтобы вы могли исследовать и понять, насколько значительна проблема.

+0

Я думаю, мой вопрос в том, каково было бы поведение, если бы этот код остался на месте? Самое большее, что мы можем сказать, это было бы неожиданно? Я хотел бы быть более конкретным. – user1660256

+0

@ user1660256 Вам нужно будет внимательно изучить конкретный код и проанализировать его взаимодействия с переходами состояния потока. Причиной предупреждения является то, что никто не хочет этого делать или рискует, что они сделают это неправильно. Отсюда предупреждение. –

+0

@ user1660256: Давид прав. трудно сказать без особого примера. Проблемы с потоками могут появляться с перерывами или на некоторых платформах, а не в других. Я бы проанализировал код и проверил случаи, когда уведомление могло быть потеряно или могло быть неправильно направлено. –

0

Нельзя подклассифицировать Thread. Это открывает множество разумно хорошо известных проблем. Использование wait/notifyAll не является отличным выбором, поскольку библиотеки параллелизма были добавлены более десяти лет назад, но в Thread это особенно плохо, потому что класс Thread также использует wait/notify для своих целей.

 Смежные вопросы

  • Нет связанных вопросов^_^