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

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

31 ответ

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

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

Еще несколько моментов (Ссылка: http://www.javaconcurrencyinpractice.com/)

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

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

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

Все вышеприведенные ответы хорошие. Вот небольшой фрагмент кода, чтобы проиллюстрировать разницу. Попробуйте это с каждым из значений true и false в 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
            }
        }
    }
}

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

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

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

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

Например, браузер 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>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Есть еще кое-что...

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

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

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

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

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

Обратите внимание на вторую последнюю строку в выходных данных ниже, когда основной поток вышел, поток демона также умер и не печатал инструкцию execute execute9 в блоке finally. Это означает, что любые ресурсы ввода / вывода, закрытые в блоке 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

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

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

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

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

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

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

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

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

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

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

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

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

setDaemon(true)

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

Любой поток Java может быть потоком демона.

Потоки демона являются поставщиками услуг для других потоков, работающих в том же процессе, что и поток демона. Например, браузер HotJava использует до четырех потоков демонов с именем "Сборщик изображений", чтобы извлекать изображения из файловой системы или сети для любого потока, который в них нуждается. run() Метод для потока демона, как правило, представляет собой бесконечный цикл, который ожидает запроса на обслуживание. Когда единственными оставшимися потоками в процессе являются потоки демона, интерпретатор завершается. Это имеет смысл, потому что, когда остаются только потоки демона, нет другого потока, для которого поток демона может предоставить сервис.

Чтобы указать, что поток является потоком демона, вызовите setDaemon метод с аргументом true. Чтобы определить, является ли поток потоком демона, используйте метод доступа isDaemon,

Надеюсь, что это может помочь!!!!!!

Я вижу, что ответов уже много; однако я хотел бы прояснить это, потому что, когда я читал о Daemon Threads, сначала у меня было ощущение, что я хорошо это понял; однако после того, как я поигрался с ним и немного отладил, я увидел странное (для меня) поведение.

Меня учили, что if I want the thread to die right after the main thread orderly finishes its execution, I should set it as *Diamond.

Я попробовал создать два потока из Main Thread, а затем я установил только один из них какDiamond. Случилось так, что после того, как ординар закончил исполнениеMain Thread, ни один из этих вновь созданных потоков не завершился. Но я ожидал, чтоDaemonпоток должен был быть завершен. Я просмотрел множество блогов и статей, но лучшее и самое четкое определение, которое я нашел до сих пор, взято из книги Java Concurrency In Practice Брайана Гетца и некоторых других.

Здесь очень четко сказано, что:

7.4.2 Демонические потоки

Иногда вы хотите создать поток, который выполняет некоторую вспомогательную функцию, но вы не хотите, чтобы существование этого потока препятствовало завершению работы JVM. Это то, для чего нужны потоки демонов. Потоки делятся на два типа: обычные потоки и потоки демонов. Когда JVM запускается, все потоки, которые она создает (например, сборщик мусора и другие вспомогательные потоки), являются потоками демона, за исключением основного потока. Когда создается новый поток, он наследует статус демона потока, который его создал, поэтому по умолчанию любые потоки, созданные основным потоком, также являются обычными потоками. Обычные потоки и потоки демонов отличаются только тем, что происходит при выходе. Когда поток завершается, JVM выполняет инвентаризацию запущенных потоков, и если единственные оставшиеся потоки являются потоками демона, она инициирует упорядоченное завершение работы. Когда JVM останавливается,все оставшиеся потоки демона прекращаются - наконец, блоки не выполняются, стеки не раскручиваются - JVM просто завершает работу. Демонические потоки следует использовать с осторожностью - некоторые операции обработки можно безопасно прекратить в любой момент без очистки. В частности, опасно использовать потоки демонов для задач, которые могут выполнять какой-либо ввод-вывод. Потоки демонов лучше всего сохранять для "служебных" задач, таких как фоновый поток, который периодически удаляет просроченные записи из кеша в памяти.Потоки демонов лучше всего сохранять для "служебных" задач, таких как фоновый поток, который периодически удаляет просроченные записи из кеша в памяти.Потоки демонов лучше всего сохранять для "служебных" задач, таких как фоновый поток, который периодически удаляет просроченные записи из кеша в памяти.

Поговорим только в коде с рабочими примерами. Мне нравится ответ Русса выше, но чтобы убрать любые сомнения, я немного их улучшил. Я запускал его дважды, один раз с рабочим потоком, установленным в 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

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

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

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

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

  • Демонические потоки - это те потоки, которые предоставляют общие службы для пользовательских потоков (пример: службы очистки - сборщик мусора)
  • Потоки демона работают все время, пока не будут уничтожены JVM
  • Демонические потоки обрабатываются иначе, чем пользовательские потоки, когда JVM завершается, наконец, блоки не называются JVM просто завершается
  • JVM не завершается, пока не завершатся все пользовательские потоки. JVM завершает работу, если все пользовательские потоки умирают
  • JVM не дожидается завершения какого-либо потока демона перед существующими, и, наконец, блоки не вызываются
  • Если все пользовательские потоки умирают, JVM убивает все потоки демона перед остановкой
  • Когда все пользовательские потоки завершены, потоки демона также могут быть завершены, и основная программа завершится
  • Метод setDaemon() должен быть вызван до вызова метода start() потока
  • После того, как поток начал выполнение, его статус демона нельзя изменить.
  • Чтобы определить, является ли поток потоком демона, используйте метод доступа isDaemon()

Вы можете превратить поток в поток демона, вызвав

t.setDaemon(true); // Call this method before starting the thread

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

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

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

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

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

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

[Демонический процесс]

Java использует user thread и концепции.

Поток JVM

      1. If there are no `user treads` JVM starts terminating the program
2. JVM terminates all `daemon threads` automatically without waiting when they are done
3. JVM is shutdown

Как видите, это служебная ветка для user treads.

  • daemon tread поток с низким приоритетом.
  • Поток наследует свои свойства от родительского потока. Чтобы установить его внешне, вы можете использовать setDaemon()Способ , прежде чем запустить его или проверить его с помощью isDaemon()

Демонические потоки - это потоки с низким приоритетом, единственная роль которых - предоставлять услуги пользовательским потокам.

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

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

Мы можем установить поток, не являющийся демоном, на демон, используя:

setDaemon(истина)

Пользовательские потоки против потоков Daemon в потоках Java

  • Нити демона

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

  • Пользовательские темы

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

«имейте в виду, что потоки пользователя и демона обернуты в потоки ОС»

Недавно OpenJdk предложил виртуальные потоки в проекте Loom (которые также основаны на пользователе), вы можете найти больше наFibersиContinuationsдля потоков виртуальной машины Java здесь .

Другие вопросы по тегам