Завершение всех дочерних потоков при закрытии рабочей области / окна
У меня есть несколько экземпляров дочерних потоков, которые запускаются и должны продолжать выполняться до завершения работы приложений.
У меня есть классы, которые расширяют задачу, и я создаю потоки как
new Thread(object of the class).start();
Все потоки должны быть завершены при закрытии первичной стадии.
primaryStage.onCloseOperation(){...}
3 ответов:
Я бы управлял вашими потоками явно с самого начала. В частности, есть пул потоков в родительском классе, например:
ExecutionService exec = Executors.newCachedExecutionService();Затем, если ваши задачи предназначены для продолжения работы (а не для периодического планирования), Закодируйте свои задачи, реагирующие на прерывание, так:
while(!Thread.currentThread().isInterrupted()){ do stuff; }Это заставит задачу работать до тех пор, пока она не будет прервана. В этом случае важно, чтобы вы никогда не игнорировали
InterruptedException, потому чтоInterruptedExceptionустанавливаетisInterruptedв false, когда они выбрасываются. Сделайте это, когда вы видитеInterruptedException:}catch(InterruptedException e){ Thread.currentThread().interrupt(); return; }Затем вы можете начать выполнение своих дочерних задач следующим образом:
Теперь, когда ваша родительская задача завершена, вы можете просто позвонить:for(task : tasks){ exec.execute(task); }exec.shutdownNow();Чтобы остановить ваши детские задачи. Если ваши дочерние задачи используют
Thread.currentThread().isInterrupted(), вы должны использоватьshutdownNow()(shutdown()работает только в том случае, если вы хотите подождать, пока задачи не остановятся сами по себе).
Вы должны подумать об использовании
ThreadGroupдля группировки всех потоков и последующего управления их поведением. Java 5 добавила классы ThreadInfo и ThreadMXBean в java.яз..управление для получения государственной информации.Вот примерный пример, чтобы достичь этого с помощью учебника доступны herehttp://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups:
Получение списка всех потоков
Другой метод enumerate () на a ThreadGroup перечисляет потоки этой группы. С истинным вторым аргументом он будет рекурсивно пересекать группу, чтобы заполнить данный массив потоковыми объектами. Начните с корневой ThreadGroup, и вы получите список всех потоков в JVM.
Проблема здесь та же, что и для перечисления групп потоков. Если массив, который вы передаете в enumerate ( ), слишком мал, некоторые потоки могут быть беззвучно удалены из возвращаемого массива. Итак, вам нужно будет угадать размер массива, вызвать enumerate (), проверить возвращаемое значение, и повторите попытку, если массив заполнен. Чтобы получить хорошее начальное предположение, посмотрите на java.яз..пакет управления. Класс ManagementFactory возвращает ThreadMXBean, метод getThreadCount () которого возвращает общее число потоков в JVM. Конечно, это может измениться мгновением позже, но это хорошая первая догадка.
Thread[] getAllThreads( ) { final ThreadGroup root = getRootThreadGroup( ); final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( ); int nAlloc = thbean.getThreadCount( ); int n = 0; Thread[] threads; do { nAlloc *= 2; threads = new Thread[ nAlloc ]; n = root.enumerate( threads, true ); } while ( n == nAlloc ); return java.util.Arrays.copyOf( threads, n ); }
Создайте
ExecutorService, который имеетThreadFactoryдля создания потоков демона.Например:
ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); return thread; } });А остальное, как его использовать, уже было сказано @Enno.
Спасибо Enno:)
Comments