2012-03-11 2 views
7

будет ли основной поток выхода до завершения дочерних потоков?будет ли основной поток выхода до завершения дочерних потоков?

я прочитал в 2 статьях

http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html

в вышеуказанной статье, в «Thread Расторжение» пункт, говорится в красном ", если родительский поток завершается, все его дочерних потоков прекращается, а также. "

http://www.roseindia.net/java/thread/overview-of-thread.shtml

в вышеуказанной статье, последняя строка в этой странице состояний «Основной() исполнение метод может закончить, но программа будет продолжать работать до тех пор, все нити не должны завершить выполнение.».

i fee они противоречивые. если я ошибаюсь, эксперты меня исправят.

В моей программе программа с методом Main вызывает конструктор из 2 потоков. в конструкторе соответствующих потоков у меня есть метод start().

 TestA A = new TestA("TestA"); 
    TestB B = new TestB("TestB"); 

    public TestA(String name) { 
    System.out.println(name); 
    t = new Thread(this); 
    t.start(); 
} 

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

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

ответ

20

Java проводит различие между пользовательским потоком и другим типом потока, известным как поток демона. Разница между этими двумя типами потоков заключается в том, что если JVM определяет, что единственными потоками, запущенными в приложении, являются потоки демона (т. Е. Нет пользовательских потоков), время выполнения Java закрывает приложение. С другой стороны, если хотя бы один пользовательский поток жив, среда выполнения Java не прекратит ваше приложение.

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

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

Я обрабатываю некоторые файлы. в тесте testA Один, только один файл не обрабатывается несколько раз. но много раз

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

Java Thread API documentation От:

Когда виртуальная машина Java запускается, то, как правило, один не-демон поток (который обычно вызывает метод, названный главным из некоторые обозначенный класс).Виртуальная машина Java продолжает выполнять потоки до тех пор, пока не произойдет одно из следующих событий:

Вызывается метод выхода класса Runtime, и менеджер безопасности разрешил операцию выхода. Все потоки , которые не являются потоками демона, умерли, либо возвратившись из вызова к методу запуска, либо путем исключения исключения, которое распространяется на за пределы метода запуска.

+0

Спасибо за подробное объяснение. вы упомянули, что «в вашем случае потоки являются пользовательскими потоками и, следовательно, разрешены для завершения до выхода основного потока». Здесь вы имеете в виду «основной поток», чтобы быть временем выполнения Java, а не программой с основным методом(). верный? – user1257836

+0

класс, который имеет основной метод и потоки, которые создаются внутри основного метода, - это все пользовательские потоки. все эти потоки независимы, и выполняются одновременно. Потому что я дал System.out.println («выход из основного метода»); в конце основного метода. это печатается до system.out.println() в дочерних потоках. это заставило меня думать, что основной поток (класс, который имеет основной метод) может выйти даже до дочерних потоков. это прекрасный и правильный способ поведения? – user1257836

+0

не могли бы вы пояснить, что вы подразумеваете под файловыми замками? заранее спасибо!! – user1257836

2

Как только основной поток выходит, он берет с собой детей. Возможно, «закончить» вторую статью просто означает не больше операции, кроме ожидания детей. Когда основной поток вызывает System.exit (0); все кончено - все тело умирает.

Скажите, что у вас есть два потока: threadA и threadB. в основном методе. Первый код является хорошим способом прекращения нити - только один из многих способов:

threadA.start(); 
threadB.start(); 
final long intercept = 300; 
long startTime = System.currentTimeMillis(); 
while (threadA.isAlive() && mis.isAlive()) { 
    threadA.join(intercept); 
if (System.currentTimeMillis() - startTime > intercept) { 
    threadB.interrupt(); 
    threadA.interrupt(); 
    threadA.join(); 
} 
} 
System.exit(0); 

Ниже скачкообразный способ убить все темы внутри основные:

System.exit(0); 
+0

Спасибо за ответ. Я никогда не использовал System.exit (0) в моей программе. «Как только основной поток выходит, он берет с собой детей» .am все еще не ясен. программа, которая имеет основной метод, создает 2 потока и их завершение.но дочерние потоки, которые были порождены, будут продолжаться, не так ли? – user1257836

3

Фоновых потоки будут продолжайте работать, даже если MAIN-поток завершен.

Если вы хотите, чтобы MAIN остановил их (например, когда MAIN завершен), пусть ваш MAIN задает переменную флага «keep running» (которую вы должны установить как «volatile»), на которую иногда смотрят потоки. MAIN задает значение false (переменная) или null (объект), когда MAIN хочет их остановить. Когда это значение false или null, поток должен быть «return;».

Это несколько сложно реализовать, существует много способов, но проще всего сделать свой Runnable внутренним классом, чтобы ваш Runnable легко делил флаг.

Для наилучших реализаций найдите эту технику в процедурах запуска/остановки Java-апплетов.

Смежные вопросы