Разница между потоком демона и потоком с низким приоритетом
Недавно мне задали вопрос:
У нас есть метод setPriority()
для установки потока для низкого приоритета. Тогда зачем нам нужен поток демона. Какая разница между ними?
Отмечает ли какой-либо поток как демона его планирование?
Ответы
Ответ 1
У нас есть метод setPriority(), чтобы установить поток для низкого приоритета. Тогда зачем нам нужен поток демона. Какая разница между ними?
Как правило, потоки демона не имеют ничего общего с приоритетом. Например, в Java JVM отключается, когда все пользовательские потоки не-daemon завершаются. Пометить поток как поток демона означает, что его можно безопасно убить, когда JVM завершает работу.
Приоритет - это планирование - о том, как часто поток получает временной срез по сравнению с другими потоками, которые готовы к запуску. У вас могут быть потоки daemon с низким приоритетом или потоки нитей с высоким приоритетом. У вас могут быть потоки не-демона, которые также имеют низкий и высокий приоритет.
Понятия ортогональны (взаимно независимы) - по крайней мере, в модели потока Java.
С точки зрения создания демона потока я использую потоки демона для любых задач, которые меня не волнуют, если они прерываются при выходе из JVM: keep-alive threads, статистические процессоры, обработка журналов и т.д. Все критически важной для приложения является не-демонный поток, который должен быть специально прерван или сигнализирован как-то выйти.
Ответ 2
Выполненный поток демона не помешает вашей программе заканчиваться/выходить. Тем не менее, все пользовательские потоки должны заканчиваться до выхода вашей программы. Приоритет может применяться как к демону, так и к пользовательскому потоку. Вы можете понимать priority
так же, как вы понимаете это в повседневной жизни.
Ответ 3
Если среда выполнения Java определяет, что единственными потоками, запущенными в приложении, являются потоки демона (т.е. нет пользовательских потоков), среда выполнения Java быстро закрывает приложение, эффективно останавливая все потоки демона в своих дорожках. Чтобы приложение продолжало работать, оно должно иметь хотя бы один поток в реальном времени. Во всех остальных аспектах среда выполнения Java обрабатывает потоки демона и пользовательские потоки точно так же.
за исключением того, что в потоке демона.. когда JVM завершается внезапно, тогда, наконец, блоки не выполняются, стеки не разматываются - JVM просто выходит. По этой причине потоки демона должны использоваться сдержанно, и их опасно использовать для задач, которые могут выполнять любые операции ввода-вывода.
Ответ 4
Пример
- Закрытие JVM при завершении нисходящей нити. Несмотря на то, что потоки Daemon все еще запущены
-
ТАКЖЕ, показывает, что поток, созданный потоком демона, автоматически становится потоком демона
package junk.daemon_thread_example;
class DeamonThreadPlus implements Runnable{
String id;
boolean createChild;
public DeamonThreadPlus(String id, boolean createChild){
this.id = id;
this.createChild = createChild;
}
@Override
public void run() {
// Parent daemon thread creates child daemon thread by default
if (createChild)
new Thread(new DeamonThreadPlus("DaemonChild", false)).start();
// This thread never self-completes (only terminates when process dies)
while (true){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Daemon "
+ Thread.currentThread().isDaemon()
+ " id = " + id);
}
}
}
class UThread implements Runnable{
@Override
public void run() {
System.out.println("User thread start");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("User thread end (program exits)");
}
}
public class Caller{
public static void main(String[] args) {
Thread dt = new Thread( new DeamonThreadPlus("Daemon", true));
dt.setDaemon(true);
dt.start();
Thread ut = new Thread(new UThread());
ut.setPriority(Thread.MIN_PRIORITY);
ut.start();
}
}
Выход:
Начало пользовательского потока
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Конечный пользовательский поток (завершение программы)
Daemon true id = DaemonChild
Daemon true id = Daemon