К. Арнольд, Д. Гослинг - Язык программирования Java (1160779), страница 40
Текст из файла (страница 40)
Имена групп, как и имена потоков, не используютсяruntime-системой. Если имя равно null, возбуждается исключение Null PointerException. Этим объекты ThreadGroup отличаются от объектовThread, у которых наличие имени необязательно.public ThreadGroup(ThreadGroup parent, String name)Создает новую группу ThreadGroup с заданным именем, принадлежащую указанной группе ThreadGroup. Как и в других конструкторах, наличиеимени является обязательным.public final String getName()Возвращает имя группы ThreadGroup.public final ThreadGroup getParent()Возвращает родительскую группу ThreadGroup или null, если ее не существует.public final void setParent(boolean daemon)Устанавливает “демонический” статус группы.public final boolean isDaemon()Возвращает “демонический” статус группы.public final synchronized void setMaxPriority(int maxPri)Устанавливает максимальный приоритет группы.public final int getMaxPriority()Возвращает текущий максимальный приоритет группы.public final boolean parentOf(ThreadGroup g)Проверяет, является ли текущая группа родителем группы g или же совпадает с ней.
Лучше представлять себе этот метод в терминах “являетсячастью”, так как группа является частью самой себя.public final void checkAccess()Возбуждает исключение SecurityException, если текущий поток не имеет права на модификацию группы. В противном случае метод простозавершается.public final synchronized void destroy()Уничтожает текущую группу типа ThreadGroup.
Группа, в которой содержатся потоки, не может быть уничтожена; при попытке сделать этовозбуждается исключение IllegalThreadStateException. Это означает, что метод destroy не может применяться для уничтожения всех потоковгруппы — это необходимо сделать вручную, воспользовавшись описанными ниже методами перечисления. Если в группу входят другие группы,то они также должны быть пустыми.Для просмотра содержимого группы используются два параллельных набора методов: один из них служит для получения информации о потоках,а другой — о группах потоков, принадлежащих данной группе. Пример использования этих методов можно найти в методе safeExit.public synchronized int activeCount()Возвращает примерное количество активных потоков в группе, включая потоки, содержащиеся в подгруппах.
Значение будет лишь примерным,поскольку к моменту его получения количество активных потоков может измениться; во время вызова activeCount одни потоки могутзавершиться, а другие — начать работу.public int enumerate(Thread[] threadsInGroup, boolean recurse)Заполняет массив threadsInGroup ссылками на все активные потоки в группе до заполнения массива. Если значение recurse равно false, топеречисляются лишь потоки, непосредственно входящие в группу; если же оно равно true, то перечисляются все потоки в иерархии. ThreadGroup.enumerate, в отличие от ThreadGroup.activeCount, позволяет определить, включаете ли вы потоки в подгруппах или нет. Это значит, что выможете получить разумную оценку для размера массива, необходимого для хранения результатов рекурсивного перечисления, однако дляперечисления, не учитывающего подгрупп, такая оценка окажется завышенной.public int enumerate(Thread[] threadsInGroup)Эквивалентно enumerate(threadsInGroup, true).public synchronized int activeGroupCount()Аналогичен методу activeCount, однако подсчитывает не потоки, а группы, в том числе и во всех подгруппах.
“Активный” (active) в данном случаеозначает “существующий”. Неактивных групп не бывает; термин используется лишь для соблюдения единого стиля с activeCount.public int enumerate(ThreadGroup[] groupsInGroup, •• boolean recurse)Аналогичен методу enumerate для потоков, однако заполняет массив ссылками на объекты-группы типа ThreadGroup вместо объектов-потоковThread.public int enumerate(ThreadGroup[] groupsInGroup)Эквивалентно enumerate(groupsInGroup, true).Объекты ThreadGroup могут также использоваться для управления потоками, входящими в группу.
Перечисленные ниже методы воздействуют навсе потоки, входящие в группу и во все ее подгруппы:public final synchronized void stop()Завершает все потоки в группе и во всех ее подгруппах.public final synchronized void suspend()Приостанавливает все потоки в группе и во всех ее подгруппах.public final synchronized void resume()Возобновляет все потоки в группе и во всех ее подгруппах.Эти методы предоставляют единственную возможность прямого использования объекта ThreadGroup для задания параметров потоков.В классе Thread также имеется два статических метода для работы с группой, в которую входит текущий поток. Они представляют собойсокращенную запись для последовательного вызова getCurrentThread, getThread Group и вызова метода для найденной группы:public static int activeCount()Возвращает количество активных потоков в группе, в которую входит текущий поток.public static int enumerate(Thread[] tarray)Возвращает количество потоков в группе, в которую входит текущий поток.Класс ThreadGroup также содержит метод, вызываемый при завершении потока, из-за неперехваченного прерывания:public void uncaughtException(Thread[] thr, Throwable exc)Вызывается при завершении потока, вызванном неперехваченным прерыванием.Данный метод является открытым, так что вы можете переопределить его для обработки неперехваченных прерываний по своему желанию.Реализация, принятая по умолчанию, вызывает метод uncaughtException группы-родителя, если таковая имеется, или метод Throwable.printStackTrace в противном случае.
Например, при разработке графической оболочки было бы желательно отобразить содержимое стека в окне,вместо того чтобы просто вывести его в System.out, как это делает метод printSt a ckTrace. Вы можете переопределить uncaughtException в своейгруппе, чтобы создать нужное окно и перенаправить в него содержимое стека.9.14. Отладка потоковНесколько методов класса Thread предназначены для облегчения отладки многопоточных приложений. Эти средства используются для выводаинформации о состоянии программы. Ниже приведен список методов класса Thread, помогающих в процессе отладки:public String toString()Возвращает строковое описание потока, включающее его имя, приоритет и имя группы.public String countStackFrames()Возвращает количество кадров стека в потоке.public static void dumpStack()Выводит в System.out содержание стека для текущего потока.Также существует ряд отладочных средств для отслеживания состояния группы потоков.
Следующие методы вызываются для объектовThreadGroup и выдают информацию об их состоянии:public String toString()Возвращает строковое описание группы, включающее ее имя и приоритет.public synchronized void list()Выводит в System.out список содержимого группы и ее подгрупп.Содержание | Далее© 1997-2002 Издательский дом "Питер". Авторские права охраняются.Предназначено только для частного использования!Воспроизведение материалов или частей данной книги в любом виде без письменного разрешения Издательского дома "Питер" запрещено!Глава 10ПАКЕТЫБиблиотека — это арсенал свободы.Источник неизвестенПод понятием “пакет” подразумевается объединение взаимосвязанных классов, интерфейсов и подпакетов.
Концепция пакета оказываетсяполезной по нескольким причинам:●●●Пакеты позволяют группировать родственные интерфейсы и классы.В интерфейсах и классах, входящих в пакет, могут использоваться популярные имена (вроде get или put), которые имеют смысл в данномконтексте, но конфликтуют с теми же именами в других пакетах.Пакет может включать типы и члены, с которыми можно работать только в пределах данного пакета.
Соответствующие идентификаторыдоступны для программ пакета, но закрыты для внешних методов.Давайте рассмотрим пример пакета для нашего класса атрибутов, использованного в предыдущих главах. Назовем пакет attr. Каждый исходныйфайл, классы и интерфейсы которого принадлежат пакету attr, должен указывать на свою принадлежность к пакету объявлением package:package attr;Тем самым объявляется, что все классы и интерфейсы, определенные в этом исходном файле, являются частью пакета attr.
Объявление packageдолжно находиться в самом начале файла, до любых объявлений классов или интерфейсов; в файле может присутствовать всего однообъявление package. Имя пакета является неявным префиксом для всех имен типов, включенных в пакет.Если фрагменту программы вне пакета понадобится обратиться к типам, входящим в пакет, у него имеется две возможности. Первая — указыватьперед каждым именем типа префикс (имя пакета). Такой вариант будет вполне разумен, если вам приходится иметь дело всего с несколькимичленами пакета.Другая возможность доступа к типам пакета заключается в частичном или полном импортировании пакета. Программист, который захочетвоспользоваться пакетом attr, может вставить следующую строку в начало своего исходного файла (после своего объявления package, но передвсем прочим):import attr.*;После этого он может обращаться к типам пакета просто по имени — например, Attributed.
Пакет неявно импортирует сам себя, так что все, чтоопределено в нем, становится доступным для всех остальных типов пакета.Механизмы package и import помогают программисту предотвращать потенциальные конфликты имен. Если в пакете, предназначенном длядругих целей (скажем, лингвистических), тоже встретится класс с именем Attributed, предназначенный для хранения языковых атрибутов, то упрограммиста, пожелавшего использовать оба пакета в одном файле, имеется несколько вариантов:●●●Обращаться к типам по их полным именам — например, attr.Attributed и lingua.Attributed.Импортировать attr.Attributed или attr.*, после чего использовать простое имя Attributed вместо attr.Attributed и полное имя lingua.Attributed.Сделать обратное — импортировать lingua.Attributed или lingua.*, после чего использовать простое имя Attributed вместо lingua.Attributed и полное имя attr.Attributed.10.1.
Имена пакетовИмя пакета должно использоваться только один раз, так что выбор содержательного и уникального имени составляет важный аспектпроектирования пакета. Однако сейчас, когда программисты всей планеты разрабатывают пакеты на языке Java, невозможно выяснить, какиеимена пакетов ими используются. Следовательно, выбор уникального имени представляет некоторую проблему. Если вы уверены, что пакетбудет использоваться только внутри вашей организации, то можно привлечь к делу выбора имени внутреннего арбитра — это позволит бытьуверенным, что все пакеты будут иметь отличающиеся имена.Тем не менее в нашем огромном мире такой подход не сработает. Идентификаторы пакетов Java представляют собой обычные имена, так чтонеплохой способ обеспечить их уникальность — включить в них имя домена организации в Internet. Если вы работаете в компании Magic, Inc., топакет с атрибутами может быть объявлен следующим образом:package COM.magic.attr;Обратите внимание: компоненты имени следуют в обратном порядке по сравнению с обычным именем домена, а имя домена верхнего уровня (внашем случае COM) написано прописными буквами.