Core
35 уровень

ThreadGroup

Статья из группы Архив info.javarush
участников
Добрый день и с новым годом! Помогите немного доразобраться с многопоточностью, а именно с ThreadGroup. Гуглил, читал, понял основную суть: назначение - безопасность, комплексное управление с помощью организации группировки.
Потоки объединяются в группы потоков (thread groups) по соображениям улучшения управляемости и безопасности. Одна группа потоков может принадлежать другой группе, составляя иерархию с основной (системной) группой на верхнем уровне. Потоки, относящиеся к группе, могут управляться единовременно – вы вправе прервать работу сразу всех потоков группы либо установить для них единое максимальное значение приоритета выполнения. Группы потоков могут быть использованы также для определения доменов безопасности. Потоки внутри группы обычно наделены возможностями взаимного влияния, распространяемого и на потоки вложенных групп. Говоря о "влиянии", мы подразумеваем, что вызов любого метода способен воздействовать на характеристики Поведения потока, скажем, изменять его приоритет или осуществлять прерывание.
(источник: Тыц)
Для того, чтобы отдельный поток не мог начать останавливать и прерывать все потоки подряд, введено понятие группы. Поток может оказывать влияние только на потоки, которые находятся в одной с ним группе. Группу потоков представляет класс ThreadGroup. Такая организация позволяет защитить потоки от нежелательного внешнего воздействия. Группа потоков может содержать другие группы, что позволяет организовать все потоки и группы в иерархическое дерево, в котором каждый объект ThreadGroup, за исключением корневого, имеет родителя.
(источник: Тыц ) Прочитав разные статьи, решил написать маленький код, в котором бы у меня не получилось из одного потока одной группы прервать потоки другой группы. И что-то не получилось: даёт прерывать((( Мой код: public class Test { public static ArrayList threads = new ArrayList(); public static ArrayList groups = new ArrayList(); public static void main(String[] args) throws InterruptedException { final ThreadGroup group1 = new ThreadGroup("GROUP 1"); final ThreadGroup group2 = new ThreadGroup("GROUP 2"); final ThreadGroup group3 = new ThreadGroup("GROUP 3"); groups.add(group1); groups.add(group2); groups.add(group3); for (int i = 0; i < groups.size(); i++) { for (int j = 1; j < 5; j++) { Thread thread = new Thread(groups.get(i), "THREAD №" + j) { @Override public void run() { while (!isInterrupted()) { try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println(getName() + " : " + getThreadGroup().getName() + " прервана"); } } } }; threads.add(thread); thread.start(); } } Thread thread = new Thread(group1, "THREAD №5") { @Override public void run() { group2.interrupt(); while (true); } }; thread.start(); threads.add(thread); for (Thread t : threads) System.out.println(t); } } Почему получается прервать? Вот вывод: Thread[THREAD №1,5,GROUP 1] Thread[THREAD №2,5,GROUP 1] Thread[THREAD №3,5,GROUP 1] Thread[THREAD №4,5,GROUP 1] Thread[THREAD №1,5,GROUP 2] Thread[THREAD №2,5,GROUP 2] Thread[THREAD №3,5,GROUP 2] Thread[THREAD №4,5,GROUP 2] Thread[THREAD №1,5,GROUP 3] Thread[THREAD №2,5,GROUP 3] Thread[THREAD №3,5,GROUP 3] Thread[THREAD №4,5,GROUP 3] Thread[THREAD №5,5,GROUP 1] THREAD №1 : GROUP 2 прервана THREAD №2 : GROUP 2 прервана THREAD №4 : GROUP 2 прервана THREAD №3 : GROUP 2 прервана
Комментарии (4)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
lichMax
Уровень 40
20 мая 2017, 11:10
Тоже тестировали влияние нитей из одной группы на нити из другой, и у меня тоже получилось прервать нить из другой группы. Но с SecurityManager'ом не разбирался, думаю, с ним может что-то получиться (судя из приведённой мной цитаты).
lichMax
Уровень 40
20 мая 2017, 11:08
По умолчанию создаваемым потокам не присваивается определенный уровень защиты. В результате любой поток из любой группы может свободно контролировать и изменять потоки в других группах. Однако можно использовать абстрактный класс SecurityManagerдля указания ограничений доступа к определенным группам потоков. Для этого необходимо создать подкласс класса SecurityManager и заменить те методы, которые используются для защиты потоков. В основном эта процедура применима для потоков приложений, так как некоторые WWW-броузеры не позволяют заменить уровни защиты.
ferasinka
Уровень 32
3 января 2017, 21:56
Решил разобраться в вашем вопросе и вот что вышло:

описание метода ThreadGroup#interrupt():
First, the checkAccess method of this thread group is called with no arguments; this may result in a security exception.


дальше в описание ThreadGroup#checkAccess():
Determines if the currently running thread has permission to modify this thread group


а теперь информация вот отсюда:
Вообще говоря, методы, затрагивающие функции безопасности, всегда загодя Проверяются соответствующим менеджером безопасности, установленным в системе. Если менеджер запрещает выполнение какого-либо действия, метод выбрасывает исключение типа SecurityException. По умолчанию при старте приложения менеджер безопасности не подключается.


Я понял так: если заранее не подключить менеджер безопасности, ограничивающий действия потоков, то по-умолчанию потоки из одной группы могут без проблем управлять потоками другой группы.
Core
Уровень 35
3 января 2017, 22:45
Ясно… Значит надо лезть в способы организации менеджеров безопасности в многопоточных приложениях… А по умолчанию, ThreadGroup нужен скорее для комплексного управления группами потоков. Например, прервать разом несколько потоков. А функционал безопасности видимо реализуется хоть и посредством этого комплексного управления, но при наличии механизма ентого самого менеджера безопасности. Что ж, спасибо. Я думал, я что-то не так реализую в своём коде.