Могут ли серверы приложений Java уничтожать потоки? Если да, то как? - PullRequest
6 голосов
/ 20 февраля 2010

Уничтожение потоков устарело в Java (и не реализовано в соответствии с javadoc), и прерывание его - всего лишь предположение, которое при выходе из потока ожидается, но не может этого сделать. (Не предоставлять какой-либо способ уничтожить поток внутри J VM - это мешающий дизайн, но мой вопрос не связан с дизайном.)

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

Извините, что я не пишу тестовые примеры для этого, но я хотел бы знать, что на самом деле там происходит.

Ответы [ 2 ]

11 голосов
/ 20 февраля 2010

Не предоставлять никакого способа уничтожения потока внутри J VM - это мешающий дизайн, но мой вопрос не связан с дизайном.

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

История состоит в том, что изначально разработчики Java пытались решить проблему уничтожения и приостановки потоков, но столкнулись с фундаментальной проблемой, которую они не могли решить в контексте языка Java.

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

Другие языки / библиотеки (например, C, C ++, C #), которые позволяют уничтожать потоки, страдают от тех же проблем, которые я описал выше, даже если соответствующие спецификации / учебники не дают ясного объяснения. Хотя можно уничтожать потоки, вы должны быть очень осторожны при разработке и реализации всего приложения, чтобы сделать это безопасно. Вообще говоря, это слишком сложно, чтобы получить право.

Итак (гипотетически), что нужно сделать, чтобы обеспечить безопасное уничтожение потоков в Java? Вот несколько идей:

  • Если в вашей JVM реализована функция Isolates, вы можете запустить вычисление, которое, возможно, захотите убить в дочернем Isolate. Проблема заключается в том, что правильно реализованный изолят может обмениваться данными с другими изолятами только путем передачи сообщений, и они, как правило, будут намного дороже в использовании.

  • Проблема общего изменяемого состояния может быть решена путем полного запрета мутации или путем добавления транзакций в модель выполнения Java. Оба из них в корне изменили бы Java.

  • Проблему ожидания / уведомления можно решить, заменив ее механизмом рандеву или передачи сообщений, который позволил «другому» потоку получить информацию о том, что поток, с которым он взаимодействовал, исчез. «Другой» поток все равно должен быть закодирован для восстановления после этого.

РЕДАКТИРОВАТЬ - В ответ на комментарии.

Взаимная блокировка Mutex не была проблемой для thread.destroy(), так как она была разработана для освобождения (разрыва) всех мьютексов, принадлежащих уничтоженному потоку. Проблема заключалась в том, что не было никаких гарантий, что структура данных, защищенная мьютексом, будет в нормальном состоянии после снятия блокировки.

Если я правильно понимаю историю этой темы, Thread.suspend(), Thread.delete() и т. Д. действительно вызывали проблемы в реальных приложениях Java 1.0. И эти проблемы были настолько серьезными и настолько трудными для разработчиков приложений, что разработчики JVM решили, что лучший способ - отказаться от методов. Это было бы непростое решение.

Теперь, если вы смелы, вы можете использовать эти методы. И в некоторых случаях они могут быть безопасными. Но построение приложения на устаревших методах не является разумной практикой разработки программного обеспечения.

2 голосов
/ 20 февраля 2010

Вам не разрешено создавать собственные потоки внутри сервера ejb.

Нередко появляются потоки в веб-контейнере (например, tomcat), хотя вы должны очень тщательно обдумать это и быть уверенным в управлении жизненным циклом этих потоков.

...