Что такое поток демона в Java?


809

Кто-нибудь может сказать мне, что потоки демона в Java ?


20
ThreadJavadoc описывает то , что они: java.sun.com/javase/6/docs/api/java/lang/Thread.html
skaffman


2
Для потоков демона, когда JVM останавливается, все потоки демона закрываются. По этой причине не следует часто использовать потоки демона, поскольку очистка на них может не выполняться. Например, любой ввод / вывод не будет грациозно завершаться и писать / читать до конца.
msj121

Ответы:


631

Поток демона - это поток, который не препятствует выходу JVM после завершения программы, но поток все еще работает. Примером потока демона является сборщик мусора.

Вы можете использовать setDaemon(boolean)метод для изменения Threadсвойств демона до запуска потока.


210
Для потомков, setDamon(boolean)может быть вызван только до того, как поток был начат. По умолчанию поток наследует статус демона своего родительского потока.
Серый

1
«не препятствует выходу JVM после завершения программы, но поток все еще работает», в то время как @sateesh говорит, что «JVM останавливает все оставшиеся потоки демона, которые были оставлены». Итак, завершаются ли потоки демонов при выходе из JVM?
Джеральд

23
@Gerald, ВСЕ потоки уничтожаются при выходе из JVM. B_erb сказал: «... когда программа закончится». Это означает, что если программа явно не уничтожает JVM, то JVM автоматически убивает себя, когда завершается последний поток, не являющийся демоном. Обычные потоки определяют «когда программа завершается». Потоки демонов этого не делают.
Соломон Медленный

2
Таким образом, эта строка в thread that does not prevent the JVM from exiting when the program finishes but the thread is still runningосновном означает, что процесс JVM, который запустил поток, не заботится о том, завершил ли выполнение поток демона или нет, он просто завершится сам, если все нормальные потоки закончили выполнение.
Bhargav

1
@SolomonSlow Каковы последствия уничтожения потока демона (например, сборщика мусора), когда он все еще выполняет свою работу, когда JVM завершает работу? Спасибо.
Венкат Рамакришнан

340

Еще несколько моментов (Ссылка: Java Concurrency in Practice )

  • Когда создается новый поток, он наследует статус демона своего родителя.
  • Когда все потоки, не являющиеся демонами, заканчивают работу, JVM останавливается, а все оставшиеся потоки демонов удаляются :

    • наконец блоки не выполняются ,
    • стеки не разматываются - JVM просто выходит.

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


3
Почему нельзя использовать потоки демона для ввода / вывода? Это беспокойство о том, что BufferedWriters и т. Д. Не сбрасываются?
Пол Кейджер

4
@PaulCager Да, они могут быть просто отрезаны в коленях во время записи / чтения.
Cruncher

52
Второй момент - чепуха. Когда JVM останавливается, все потоки умирают и finallyблоки не выполняются, независимо от того, являются ли потоки демонами или нет. Так что не звоните, System.exit(…)если вы думаете, что могут быть запущенные потоки, делающие ввод / вывод. Единственное отличие состоит в том, что JVM будет запускать свое собственное завершение, когда остаются только потоки демона.
Хольгер

11
Что подразумевается под "стеки не размотаны"?
ʀɛɔʘɴ ʀɛɔʘɴ

2
@ ɢʜʘʂʈʀɛɔʘɴ Есть несколько объяснений «раскручивания стеков», включая это: flylib.com/books/en/2.254.1.277/1
user766353

175

Все вышеприведенные ответы хороши. Вот небольшой фрагмент кода, чтобы проиллюстрировать разницу. Попробуйте это с каждым из значений true и false in setDaemon.

public class DaemonTest {

    public static void main(String[] args) {
        new WorkerThread().start();

        try {
            Thread.sleep(7500);
        } catch (InterruptedException e) {
            // handle here exception
        }

        System.out.println("Main Thread ending") ;
    }

}

class WorkerThread extends Thread {

    public WorkerThread() {
        // When false, (i.e. when it's a user thread),
        // the Worker thread continues to run.
        // When true, (i.e. when it's a daemon thread),
        // the Worker thread terminates when the main 
        // thread terminates.
        setDaemon(true); 
    }

    public void run() {
        int count = 0;

        while (true) {
            System.out.println("Hello from Worker "+count++);

            try {
                sleep(5000);
            } catch (InterruptedException e) {
                // handle exception here
            }
        }
    }
}

2
@russ Хороший фрагмент кода! Я должен был определить класс WorkerThread как статический.
XL

@xli, ты мог бы сделать новый DaemonTest (). new WorkerThread (). start () тоже :)
abhy

@ хороший пример. Мне было известно о том, что значением по умолчанию является «setDeamon (false)», если вы явно не определили «setDaemon (true)»
huseyin

96

Традиционно демон-процессы в UNIX были такими, которые постоянно работали в фоновом режиме, во многом как сервисы в Windows.

Поток демона в Java - тот, который не препятствует выходу JVM. В частности, JVM завершит работу, когда останутся только потоки демона. Вы создаете его, вызывая setDaemon()метод Thread.

Прочитайте темы Демона .


3
ваша ссылка в данный момент не работает, возможно, вы хотите обновить? в любом случае +1 для вас.
Джейсон

2
Мне нравится сравнение между UNIX и Windows.
Премрай

Лучшее объяснение здесь!
LoveMeow

57

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

Например, браузер HotJava использует до четырех потоков демонов с именем «Сборщик изображений» для извлечения изображений из файловой системы или сети для любого потока, который в этом нуждается.

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

setDaemon (true / false)? Этот метод используется, чтобы указать, что поток является потоком демона.

public boolean isDaemon ()? Этот метод используется для определения того, является ли поток потоком демона или нет.

Например:

public class DaemonThread extends Thread {
    public void run() {
        System.out.println("Entering run method");

        try {
            System.out.println("In run Method: currentThread() is" + Thread.currentThread());

            while (true) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException x) {}

                System.out.println("In run method: woke up again");
            }
        } finally {
            System.out.println("Leaving run Method");
        }
    }
    public static void main(String[] args) {
        System.out.println("Entering main Method");

        DaemonThread t = new DaemonThread();
        t.setDaemon(true);
        t.start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException x) {}

        System.out.println("Leaving main method");
    }

}

Вывод:

C:\java\thread>javac DaemonThread.java

C:\java\thread>java DaemonThread
Entering main Method
Entering run method
In run Method: currentThread() isThread[Thread-0,5,main]
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
Leaving main method

C:\j2se6\thread>

37

Определение демона (вычислений):

Фоновый процесс, который обрабатывает запросы на такие службы, как спулинг печати и передача файлов, и бездействует, когда не требуется.

—— Источник: английский от Оксфордских словарей

Что такое поток демонов в Java?

  • Потоки демона могут в любой момент прерваться между своими потоками, не-демон, то есть пользовательский поток выполняется полностью.
  • Потоки демона - это потоки, которые периодически запускаются в фоновом режиме, пока работают другие потоки, не являющиеся демонами.
  • После завершения всех потоков, не являющихся демонами, потоки демонов завершаются автоматически.
  • Потоки демона являются поставщиками услуг для пользовательских потоков, работающих в одном и том же процессе.
  • JVM не заботится о том, чтобы потоки демона завершались, когда он находится в состоянии Running, даже блок finally не позволяет выполнять. JVM отдает предпочтение созданным нами потокам, не являющимся демонами.
  • Потоки демона действуют как службы в Windows.
  • JVM останавливает потоки демона, когда все пользовательские потоки (в отличие от потоков демона) завершаются. Следовательно, потоки демона могут использоваться, например, для реализации функциональности мониторинга, поскольку поток останавливается JVM, как только все пользовательские потоки останавливаются.

если вы вызываете System.exit (), блоки finally не выполняются, независимо от того, является ли поток потоком демона. действительно, наконец, блоки выполняются в потоках демона даже после того, как последний пользовательский поток завершается, если JVM еще не уничтожила поток
Benez

5
Поток демона выполняется с тем же приоритетом, что и поток его создания, если только он не был изменен перед запуском. Потоки демона не обязательно являются «поставщиками сервисов», или сервисами Windows, или чем-то еще, что здесь указано: это просто потоки, которые не препятствуют выходу JVM. Период.
Маркиз Лорн

35

Демон поток является потоком , который считается делать некоторые задачи в фоновом режиме , таких как обработка запросов или различных chronjobs , которые могут существовать в приложении.

Когда в вашей программе остались только потоки демонов, она завершится. Это потому, что обычно эти потоки работают вместе с обычными потоками и обеспечивают фоновую обработку событий.

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


1
Это потому, что это поток демона, и это означает «демон». Ваши рассуждения вернулись на фронт.
Маркиз Лорн

15

Одно заблуждение я хотел бы уточнить:

  • Предположим, что если поток демона (скажем, B) создан в пользовательском потоке (скажем, A); тогда окончание этого пользовательского потока / родительского потока (A) не завершит созданный им поток демона / дочерний поток (B); предоставленный пользовательский поток является единственным запущенным в данный момент.
  • Таким образом, в окончании потока нет отношения родитель-потомок. Все потоки демона (независимо от того, где он был создан) завершатся, когда не будет ни одного живого пользовательского потока, и это приведет к завершению JVM.
  • Даже это верно для обоих (parent / child) - потоки демона.
  • Если дочерний поток создан из потока демона, то это также поток демона. Это не потребует явной установки флага потока демона. Точно так же, если дочерний поток создан из пользовательского потока, то это также пользовательский поток, если вы хотите изменить его, то перед началом работы этого дочернего потока необходима явная установка флага демона.

Это не процитировано ни от чего. Не используйте форматирование цитаты для текста, который не цитируется. Первый абзац «цитаты» неверен и противоречит второму.
Маркиз Лорн

@ EJP ПОЛУЧИЛ ЭТО, так что каждый должен давать цитаты другим людям, а не своим. ИЛИ сами что-то цитировали, тогда укажите здесь?
Канагавелу Сугамар

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

12

Демоническая и пользовательская темы. Обычно все потоки, созданные программистом, являются пользовательскими (если вы не укажете, что это демон, или ваш родительский поток не является потоком демона). Пользовательский поток обычно предназначен для запуска нашего программного кода. JVM не завершается, если не завершен весь поток пользователя.


10

У Java есть специальный вид потока, называемый потоком демона .

  • Очень низкий приоритет.
  • Выполняется только тогда, когда не запущен другой поток из той же программы.
  • JVM завершает программу, заканчивая эти потоки, когда потоки демона являются единственными потоками, работающими в программе.

Для чего используются потоки демонов?

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

Типичным примером такого рода потоков является сборщик мусора Java .

Есть больше...

  • Вы вызываете setDaemon()метод только перед вызовом start()метода. Когда поток запущен, вы не можете изменить его состояние демона.
  • Используйте isDaemon()метод, чтобы проверить, является ли поток потоком демона или потоком пользователя.

8
-1, я не верю, что поток демона по своей природе имеет низкий приоритет. Конечно, нет документации, я видел такие состояния. Также в этом ответе SO утверждается, что приоритет и демон являются ортогональными: stackoverflow.com/a/10298353/839128
MikeFHay,

5
Потоки демона не имеют ничего общего с приоритетом. Вы можете иметь поток демона с высоким приоритетом или поток демона с низким приоритетом.
Серый

Первоначально поток демона имеет тот же приоритет, что и поток создания.
Маркиз Лорн

Выражение «выполняется только тогда, когда ни один другой поток из той же программы не запущен» вводит в заблуждение.
Фредрик Гаусс

9

Нити демонов похожи на помощников. Non-Daemon темы как фронт-исполнители. Помощники помогают исполнителям завершить работу. Когда работа завершена, исполнители больше не нуждаются в помощи. Поскольку помощь не требуется, помощники покидают это место. Поэтому, когда задания потоков, не являющихся демонами, заканчиваются, потоки демонов удаляются.


5

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


5

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

Указывает на Примечание:

  1. Любой поток, созданный основным потоком, который выполняет основной метод в Java, по умолчанию не является демоном, поскольку поток наследует свою природу демона от потока, который его создает, т.е. родительский поток, а поскольку основной поток является потоком, не являющимся демоном, любой другой поток, созданный из него оставаться не-демоном до тех пор, пока он не будет явно создан, вызывая setDaemon (true).

  2. Thread.setDaemon (true) создает демон Thread, но его можно вызвать только перед запуском Thread в Java. Он выдаст исключение IllegalThreadStateException, если соответствующий поток уже запущен и работает.

Разница между потоками Daemon и Non Daemon в Java:

1) JVM не ожидает завершения работы какого-либо потока демона перед его созданием.

2) Поток демона обрабатывается иначе, чем пользовательский поток, когда JVM завершается, наконец, блоки не вызываются, стеки не разматываются, а JVM просто выходит.


5

В Java потоки Daemon являются одним из типов потока, который не препятствует выходу виртуальной машины Java (JVM). Основная цель потока демона - выполнить фоновую задачу, особенно в случае какой-либо рутинной периодической задачи или работы. С выходами JVM поток демона также умирает.

При установке a thread.setDaemon(true)поток становится потоком демона. Однако вы можете установить это значение только до начала потока.


Какие другие типы потоков, которые делают это? A: Нет. Существуют потоки демонов и не демонов, точка. Это двоичный файл, два состояния.
маркиз Лорн

5

Вот пример для тестирования поведения потоков демона в случае выхода из jvm из-за отсутствия пользовательских потоков.

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

public class DeamonTreadExample {

public static void main(String[] args) throws InterruptedException {

    Thread t = new Thread(() -> {
        int count = 0;
        while (true) {
            count++;
            try {
                System.out.println("inside try"+ count);
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                System.out.println("finally executed"+ count);
            }
        }
    });
    t.setDaemon(true);
    t.start();

    Thread.currentThread().sleep(10000);
    System.out.println("main thread exited");
  }
}

Вывод

inside try1
finally executed1
inside try2
finally executed2
inside try3
finally executed3
inside try4
finally executed4
inside try5
finally executed5
inside try6
finally executed6
inside try7
finally executed7
inside try8
finally executed8
inside try9
finally executed9
inside try10
main thread exited

4

Потоки демонов, как все объяснили, не будут ограничивать выход из JVM, так что в основном это счастливый поток для Application с точки зрения выхода.

Хочу добавить, что потоки демона можно использовать, когда, скажем, я предоставляю такой API, как отправка данных на сторонний сервер или JMS, мне может потребоваться агрегировать данные на уровне клиентской JVM и затем отправлять их в JMS в отдельном потоке. Я могу сделать этот поток потоком демона, если это не обязательные данные для отправки на сервер. Этот тип данных похож на журнал регистрации / агрегации.

С уважением, Маниш


Вот простая программа, показывающая поток демона в Java. journaldev.com/1072/java-daemon-thread-example
Pankaj

4

Поток демона похож на процесс демона, который отвечает за управление ресурсами, виртуальная машина Java создает поток демона для обслуживания пользовательских потоков. пример обновления системы для unix, unix - это процесс-демон. Дочерний поток демона всегда является потоком демона, поэтому по умолчанию он имеет значение false. Вы можете проверить поток как демон или пользователь, используя метод isDaemon (). поэтому поток демона или процесс демона в основном отвечают за управление ресурсами. например, когда вы запускаете jvm, запускается сборщик мусора, который является потоком демона с приоритетом 1, который является самым низким, который управляет памятью. jvm жив, пока жив пользовательский поток, вы не можете уничтожить поток демона. jvm отвечает за уничтожение потоков демона.


Очень смущен, и все это не являются следствием.
Маркиз Лорн

3

Поговорим только в коде с рабочими примерами. Мне нравится ответ Русса выше, но чтобы убрать любые сомнения, я немного их улучшил. Я запускал его дважды, один раз с рабочим потоком, установленным в deamon true (поток deamon), а в другой раз установил его в false (пользовательский поток). Это подтверждает, что поток deamon заканчивается, когда заканчивается основной поток.

public class DeamonThreadTest {

public static void main(String[] args) {

    new WorkerThread(false).start();    //set it to true and false and run twice.

    try {
        Thread.sleep(7500);
    } catch (InterruptedException e) {
        // handle here exception
    }

    System.out.println("Main Thread ending");
    }
   }

   class WorkerThread extends Thread {

    boolean isDeamon;

    public WorkerThread(boolean isDeamon) {
        // When false, (i.e. when it's a user thread),
        // the Worker thread continues to run.
        // When true, (i.e. when it's a daemon thread),
        // the Worker thread terminates when the main
        // thread terminates.
        this.isDeamon = isDeamon;
        setDaemon(isDeamon);
    }

    public void run() {
        System.out.println("I am a " + (isDeamon ? "Deamon Thread" : "User Thread (none-deamon)"));

        int counter = 0;

        while (counter < 10) {
            counter++;
            System.out.println("\tworking from Worker thread " + counter++);

            try {
                sleep(5000);
            } catch (InterruptedException e) {
                // handle exception here
            }
        }
        System.out.println("\tWorker thread ends. ");
    }
}



result when setDeamon(true)
=====================================
I am a Deamon Thread
    working from Worker thread 0
    working from Worker thread 1
Main Thread ending

Process finished with exit code 0


result when setDeamon(false)
=====================================
I am a User Thread (none-deamon)
    working from Worker thread 0
    working from Worker thread 1
Main Thread ending
    working from Worker thread 2
    working from Worker thread 3
    working from Worker thread 4
    working from Worker thread 5
    working from Worker thread 6
    working from Worker thread 7
    working from Worker thread 8
    working from Worker thread 9
    Worker thread ends. 

Process finished with exit code 0

3

Потоки демонов обычно называются потоками «Service Provider». Эти потоки должны использоваться не для выполнения программного кода, а для системного кода. Эти потоки работают параллельно вашему коду, но JVM может уничтожить их в любое время. Когда JVM не находит пользовательских потоков, он останавливает его, и все потоки демона мгновенно завершаются. Мы можем установить поток, не являющийся демоном, в демон, используя:

setDaemon(true)

3
Они не «общеизвестны как« потоки поставщика услуг ».
маркиз Лорн

1
И они могут быть использованы для выполнения любого кода. JVM не может «убить их в любое время», но это будет убивать их , когда нет не-демон нити работает.
маркиз Лорн

@EJP, может быть, я ошибаюсь, но «он убьет их», когда запущены не демонные потоки. Когда поток является демоном, не запускается ли он отдельно, удерживая jvm, пока он не выполнится полностью и теперь не будет управляться на уровне ОС.
89n3ur0n

Он убьет их, когда все потоки, не являющиеся демонами, завершат работу, а не пикосекунду раньше. Конечно, не «в любое время».
Маркиз Лорн

3

Потоки демона - это потоки, которые работают в фоновом режиме, пока другие потоки процесса, не являющиеся демонами, все еще работают. Таким образом, когда все потоки, не являющиеся демонами, завершаются, потоки демонов завершаются. Примером потока, не являющегося демоном, является поток, выполняющий Main. Поток становится демоном, вызываяsetDaemon() метод до запуска потока

Для дополнительной справки: Демоническая нить в Java


2

Для меня нить демона это как экономка для пользовательских тем. Если все пользовательские потоки завершены, поток демонов не имеет работы и уничтожен JVM. Я объяснил это в видео на YouTube .


2

JVM выполнит работу, когда завершится выполнение последнего потока, не являющегося демоном. По умолчанию JVM создает поток как не-демон, но мы можем сделать поток как демон с помощью метода setDaemon(true). Хорошим примером потока Daemon является поток GC, который завершит свою работу, как только будут завершены все потоки, не являющиеся демонами.


как это может быть, как работает поток GC? Не запускается ли сборка мусора, даже если основной поток программы занимает очень много времени (основной поток не прерывается)?
Каликодер

Как я уже упоминал, поток GC будет работать до конца последнего потока NON-демона, который завершит свое выполнение. Как мы знаем, основной поток программы не является демоном, поэтому поток GC выполнит работу, как только основной поток будет завершен / уничтожен. По сути, я хочу сказать, что поток (ы) демона будет прерван, когда процесс завершится, и процесс завершится, когда будут выполнены все потоки, не являющиеся демонами.
Арман Туманян

По умолчанию статус демона потока наследуется от его родителя.
Маркиз Лорн

-1

Нити демона умирают при выходе из нити создателя.

Потоки, не являющиеся демонами (по умолчанию), могут даже жить дольше, чем основной поток.

if ( threadShouldDieOnApplicationEnd ) {
    thread.setDaemon ( true );
}
thread.start();

Это не верно. Это не о создателя темы. Если работает ЛЮБОЙ не пользовательский поток, потоки демона продолжат работать. Это легко проверить, создав поток переднего плана, который порождает поток демона. Даже после редактирования потока переднего плана join, демон будет оставаться до тех пор, пока работает основной поток.
Юбер Гжесковяк,

Потоки демона умирают, когда JVM перестает быть работоспособными потоками, не являющимися демонами. Смотрите Javadoc. Ответ совершенно неверный.
Маркиз Лорн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.