Главная » Java » Стратегии закрытия системы

0

 

   Вообще говоря, следует всегда предпочитать нормальное завершение программы ее принудительному закрытию посредством вызова exit. Этот тезис особенно справедлив в отношении многопоточных приложений, когда поток, принимающий решение о завершении всего приложения, может не обладать достаточной информацией о том, чем в этот момент занимаются все остальные потоки.

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

   Чтобы потоки приложения смогли воспринять требование о необходимости завершения работы, они должны быть способны реагировать на вызов метода interrupt (см. раздел 10.8.1). При обращении к методу interrupt родительского объекта ThreadGroup приложения всем потокам последнего рассылается запрос на завершение. Впрочем, гарантий того, что выполнение программы будет непременно завершено, не существует, поскольку используемые приложением библиотеки вправе создавать пользовательские потоки, которые просто не отвечают на запросы прерывания, — одним из подобных примеров может служить графическая библиотека AWT.

  Существуют две ситуации, когда без вызова метода exit обойтись нельзя — если таковой представляет собой единственный способ завершения некоторых потоков (и следовательно, приложения в целом) и если приложение обязано вернуть во внешнюю среду код завершения (exit value). В обоих случаях надлежит обеспечить задержку вызова exit до того момента, пока все потоки приложения не получат возможности завершить свою работу корректно и "чисто". Один из способов достижения этой цели потоком, инициировавшим завершение, состоит в объединении (join) его с другими потоками, чтобы получить возможность "узнать" об окончании их работы. Впрочем, приложению может понадобиться поддерживать и собственный список созданных им потоков, поскольку при простом запросе к ThreadGroup могут быть возвращены ссылки на библиотечные потоки, которые не завершают свое выполнение, так что вызов join для них не вернет ничего.

  Решение о завершении работы приложения должно приниматься кодом самого верхнего уровня — чаще всего методом main или методом run объекта потока, относящегося к объекту ThreadGroup приложения, либо кодом, ответственным за реакцию на события, возникающие в графическом интерфейсе пользователя. Методы, в процессе выполнения встречающиеся с ошибками, обязаны просто фиксировать факт их появления и передавать соответствующую информацию в виде объектов исключений коду верхнего уровня, который вправе при-

нимать соответствующие решения. Прикладной код не долженлгрекращать работу всего приложения ввиду возникновения ошибки (ему явно не хватит необходимых "знаний", чтобы принять решение, отвечающее ситуации наилучшим образом) — для передачи данных об ошибке коду верхнего уровня уместно воспользоваться объектом исключения требуемого типа.

 

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии