什么是Java中的守护程序线程?

时间:2010-02-06 14:08:37

标签: java multithreading

有人能告诉我Java中的守护程序线程是什么吗?

28 个答案:

答案 0 :(得分:582)

守护程序线程是一个线程,它在程序完成但线程仍在运行时不会阻止JVM退出。守护程序线程的一个示例是垃圾收集。

您可以在线程启动之前使用setDaemon(boolean)方法更改Thread守护程序属性。

答案 1 :(得分:323)

还有几点(参考:Java Concurrency in Practice

  • 创建新线程时,它会继承其线程的守护程序状态 父节点。
  • 当所有非守护程序线程完成时,JVM停止,任何剩余的守护程序线程被放弃

    • 最终未执行块
    • 堆栈没有解开 - JVM刚刚退出。

    由于这个原因,应该谨慎使用守护程序线程,将它们用于可能执行任何类型I / O的任务是危险的。

答案 2 :(得分:166)

以上所有答案都很好。这是一个简单的小代码片段,用于说明差异。在setDaemon中使用true和false中的每个值进行尝试。

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
            }
        }
    }
}

答案 3 :(得分:95)

UNIX中的传统守护进程是那些在后台不断运行的进程,就像Windows中的服务一样。

Java中的守护程序线程不会阻止JVM退出。特别是当只剩下守护程序线程时,JVM将退出。您可以在setDaemon()上调用Thread方法创建一个。

阅读Daemon threads

答案 4 :(得分:57)

守护程序线程就像是与守护程序线程在同一进程中运行的其他线程或对象的服务提供程序。守护程序线程用于后台支持任务,仅在正常线程执行时才需要。如果正常线程没有运行而剩余线程是守护线程,则解释器退出。

例如,HotJava浏览器最多使用四个名为“Image Fetcher”的守护程序线程从文件系统或网络中获取需要的任何线程的图像。

守护程序线程通常用于为您的应用程序/ applet执行服务(例如加载“fiddley位”)。用户线程和守护程序线程之间的核心区别是,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>

答案 5 :(得分:33)

守护程序线程是一个被认为在后台执行某些任务的线程,如处理请求或应用程序中可能存在的各种chronjobs。

如果您的程序只剩下守护程序线程,它将退出。这是因为通常这些线程与普通线程一起工作并提供事件的后台处理。

您可以使用Thread方法指定setDaemon守护程序,它们通常不会退出,也不会被中断..它们只会在申请停止。

答案 6 :(得分:32)

守护进程(计算)的定义:

  

后台进程,用于处理打印假脱机和文件传输等服务请求,并在不需要时处于休眠状态。

- 资料来源:English by Oxford Dictionaries

Java中的守护程序线程是什么?

  • 守护程序线程可以在其流程之间的任何时间关闭,非守护程序即用户线程完全执行。
  • 守护程序线程以低优先级执行。
  • 守护程序线程是在后台间歇运行的线程,只要其他非守护程序线程正在运行。
  • 当所有非守护程序线程完成时,守护程序线程会自动终止。
  • 守护程序线程是在同一进程中运行的用户线程的服务提供程序。
  • JVM不关心守护程序线程在运行状态下完成,甚至不是finally块也让let执行。 JVM确实优先考虑由我们创建的非守护程序线程。
  • 守护程序线程在Windows中充当服务。
  • 当所有用户线程(与守护程序线程相反)终止时,JVM会停止守护程序线程。因此,守护程序线程可用于实现监视功能,因为一旦所有用户线程都停止,JVM就会停止该线程。

答案 7 :(得分:15)

我想澄清一个误解:

  • 假设如果在用户线程中创建了守护程序线程(比如说B)(比如说) 一个);那么这个用户线程/父线程(A)的结尾将不会结束 它创建的守护程序线程/子线程(B);提供的用户线程是唯一的 一个正在运行。
  • 因此线程结束时没有父子关系。一旦没有单个实时用户线程并且导致JVM终止,所有守护程序线程(无论它在何处创建)都将结束。
  • 即使对于(父/子)都是守护程序线程也是如此。
  • 如果从守护程序线程创建子线程,那么它也是守护程序线程。这不需要任何显式守护程序线程标志设置。 类似地,如果从用户线程创建的子线程然后也是用户线程,如果要更改它,则在启动该子线程之前需要显式守护程序标志设置。

答案 8 :(得分:12)

守护程序线程和用户线程。通常,程序员创建的所有线程都是用户线程(除非您将其指定为守护程序或您的父线程是守护程序线程)。用户线程通常用于运行我们的程序代码。除非所有用户线程都终止,否则JVM不会终止。

答案 9 :(得分:12)

Java有一种称为守护程序线程的特殊线程。

  • 非常低优先级。
  • 仅在同一程序的其他线程未运行时执行。
  • 当守护程序线程结束时,JVM结束程序完成这些线程 程序中运行的唯一线程。

守护程序线程用于什么?

通常用作普通线程的服务提供者。 通常有一个等待服务请求或执行线程任务的无限循环。 他们不能做重要的工作。 (因为我们不知道他们何时会有CPU时间,如果没有其他线程在运行,他们可以随时完成。)

这类线程的典型示例是 Java垃圾收集器

还有更多......

  • 在调用setDaemon()方法之前,您只能调用start()方法。线程运行后,您无法修改其守护程序状态。
  • 使用isDaemon()方法检查线程是守护程序线程还是用户线程。

答案 10 :(得分:8)

守护程序线程就像助手一样。非守护进程线程就像前面的表演者。助理帮助表演者完成一份工作。作业完成后,表演者不再需要帮助。由于不需要任何帮助,助理离开了这个地方。因此,当非守护程序线程的作业结束时,守护程序线程就会消失。

答案 11 :(得分:5)

守护程序线程就像普通线程一样,只是当其他非守护程序线程不存在时,JVM才会关闭。守护程序线程通常用于为您的应用程序执行服务。

答案 12 :(得分:5)

Java中的守护程序线程是那些在后台运行的线程,主要由JVM创建,用于执行垃圾收集和其他内务处理任务等后台任务。

注意事项:

  1. 由主线程创建的任何线程(在Java中运行main方法)默认为非守护进程,因为Thread从创建它的Thread继承其守护进程性质,即父线程,因为主线程是非守护进程线程,任何从它创建的其他线程将保持非守护进程,直到通过调用setDaemon(true)显式创建守护进程。

  2. Thread.setDaemon(true)创建一个Thread守护程序,但只能在启动Thread中的Java之前调用它。如果相应的Thread已经启动并运行,它将抛出IllegalThreadStateException。

  3. Java中守护程序和非守护程序线程之间的区别:

    1)JVM不会等待任何守护程序线程在现有之前完成。

    2)当JVM终止时,守护进程线程的处理方式与用户线程不同,最后不会调用块,堆栈不会被解除,JVM就会退出。

答案 13 :(得分:4)

守护程序线程类似于守护程序进程,它负责管理资源,Java VM创建一个守护程序线程来为用户线程提供服务。 unix的示例更新系统,unix是守护进程。 守护程序线程的子程序始终是守护程序线程,因此默认情况下守护程序为false。您可以使用" isDaemon()"将线程检查为守护程序或用户。方法。 所以守护进程线程或守护进程基本上负责管理资源。 例如,当你启动jvm时,会运行垃圾收集器,它是守护程序线程,其优先级为1,它是最低的,即管理内存。 只要用户线程处于活动状态,jvm就处于活动状态,你无法杀死守护进程thread.jvm负责杀死守护进程线程。

答案 14 :(得分:4)

守护程序线程通常称为“服务提供程序”线程。这些线程不应该用于执行程序代码而是用于系统代码。这些线程与您的代码并行运行,但JVM可以随时终止它们。当JVM找不到用户线程时,它会停止它并且所有守护程序线程立即终止。我们可以使用以下命令将非守护程序线程设置为守护程序:

setDaemon(true)

答案 15 :(得分:4)

在Java中,Daemon Threads是不阻止Java虚拟机(JVM)退出的线程类型之一。 守护程序线程的主要目的是执行后台任务,尤其是在某些例行定期任务或工作的情况下。随着JVM退出,守护程序线程也会死掉。

通过设置thread.setDaemon(true),线程成为守护线程。但是,您只能在线程开始之前设置此值。

答案 16 :(得分:4)

守护程序线程正如大家所解释的那样,不会限制JVM退出,所以从出口的角度来看,它基本上是一个应用程序的快乐线程。

想要添加守护程序线程可以在我提供像将数据推送到第三方服务器/或JMS的API时使用,我可能需要在客户端JVM级别聚合数据然后发送到JMS中单独的线程。我可以将此线程作为守护程序线程,如果这不是要推送到服务器的必需数据。 这种数据类似于日志推送/聚合。

此致 和Manish

答案 17 :(得分:3)

任何Java线程都可以是守护程序线程。

守护程序线程是与守护程序线程在同一进程中运行的其他线程的服务提供程序。例如, HotJava浏览器最多使用四个名为" Image Fetcher" 的守护程序线程,从文件系统或网络中获取需要的任何线程的图像一。守护程序线程的 run() 方法通常是等待服务请求的无限循环。 当进程中唯一剩余的线程是守护程序线程时,解释器退出。这是有道理的,因为当只剩下守护程序线程时,没有其他线程,守护程序线程可以为其提供服务。

要指定线程是守护程序线程,请使用参数true调用 setDaemon 方法。要确定某个线程是否是守护程序线程,请使用访问者方法 isDaemon

希望这可能有所帮助!!!!!!

答案 18 :(得分:3)

守护程序线程是在后台运行的线程,只要该进程的其他非守护程序线程仍在运行。因此,当所有非守护程序线程完成时,守护程序线程终止。非守护程序线程的一个示例是运行Main的线程。 通过在线程启动之前调用setDaemon()方法使线程成为守护进程

更多参考资料:Daemon thread in Java

答案 19 :(得分:2)

对我来说,守护程序让它成为用户线程的管家。 如果所有用户线程都已完成,则守护程序线程没有作业 被JVM杀死。 我在YouTube video中解释了它。

答案 20 :(得分:2)

我们只在代码中讨论一些工作示例。我喜欢上面的russ答案,但为了消除我的任何疑问,我加强了一点点。我运行了两次,一次将工作线程设置为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

答案 21 :(得分:2)

JVM将在最后一次非守护程序线程执行完成时完成工作。默认情况下,JVM将创建一个作为nondaemon的线程,但我们可以在方法setDaemon(true)的帮助下将Thread作为守护进程。守护程序线程的一个很好的例子是GC线程,它将在所有非守护程序线程完成后立即完成其工作。

答案 22 :(得分:2)

  • 守护程序线程是那些为用户线程提供常规服务的线程(例如:清理服务-垃圾收集器)
  • 守护进程线程一直运行,直到被JVM杀死
  • 当JVM终止时,守护进程线程与用户线程的处理方式有所不同,最终块不被称为JVM而是直接退出
  • 除非所有用户线程都终止,否则
  • JVM不会终止。如果所有用户线程都死了,JVM将终止
  • JVM不等待任何守护进程线程完成,然后再不调用现有的finally块
  • 如果所有用户线程死亡,则JVM会在停止之前杀死所有守护程序线程
  • 所有用户线程终止后,守护程序线程也可以终止,主程序也终止
  • 必须在调用线程的start()方法之前调用
  • setDaemon()方法
  • 一旦线程开始执行其守护程序状态,就无法更改
  • 要确定线程是否是守护线程,请使用访问器方法isDaemon()

答案 23 :(得分:1)

守护程序线程在创建者线程退出时死亡。

非守护程序线程(默认)甚至可以比主线程更长寿。

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

答案 24 :(得分:1)

以下是一个示例,在jvm退出的情况下,由于不存在用户线程而测试守护程序线程的行为。

请注意下面输出中的第二行,当主线程退出时,守护程序线程也死了,并且在finally块中没有打印 finally execution9 语句。这意味着如果由于不存在用户线程而导致JVM退出,则在守护程序线程的finally块内关闭的任何i / o资源都不会被关闭。

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

答案 25 :(得分:1)

我看到,已经有很多答案了;但是,我希望对此有个更清晰的了解,因为当我阅读有关 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线程应该已经退出。我浏览了许多博客和文章,但是到目前为止,我发现的最好和最清晰的定义来自Brian Goetz等人撰写的 Java Concurrency In Practice 书。

很清楚地说:

7.4.2守护程序线程

有时您想创建一个执行一些帮助的线程 功能,但您不希望该线程的存在阻止 JVM从关闭。这就是守护线程的用途。 线程分为两种类型:普通线程和守护程序线程。 JVM启动时,它创建的所有线程(例如垃圾) 收集器和其他内部管理线程)是守护程序线程,但 主线程。创建新线程时,它将继承守护程序 创建它的线程的状态,因此默认情况下所有线程 由主线程创建的也是普通线程。普通螺纹和 守护程序线程仅在退出时发生的事情有所不同。当一个 线程退出时,JVM执行正在运行的线程的清单,如果 剩下的唯一线程是守护程序线程,它启动 有序关机。 JVM停止时,所有剩余的守护程序线程都会 放弃-最终不执行块,不展开堆栈- JVM刚刚退出。应当谨慎使用守护程序线程-很少处理 活动可以随时安全地放弃而无需清理。在 特别是,将守护程序线程用于可能 执行任何类型的I / O。最好将守护进程线程保存为 “整理”任务,例如定期执行的后台线程 从内存缓存中删除过期的条目。

答案 26 :(得分:1)

守护程序线程是低优先级线程,其唯一作用是为用户线程提供服务。

守护进程线程通常由JVM为后台任务创建,而用户线程则由应用程序为前台任务创建。

因为守护程序线程是为用户线程服务的,并且仅在用户线程运行时才需要,所以它们不会阻止JVM在所有用户线程完成执行后退出。

我们可以使用以下命令将非守护程序线程设置为守护程序:

setDaemon(true)

答案 27 :(得分:1)

Java 守护线程

[Daemon process]

Java 使用 user threaddaemon tread 概念。

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

如您所见,daemon treaduser treads服务线程

  • daemon tread 是低优先级线程。
  • 线程从父线程继承其属性。要在外部设置它,您可以使用 setDaemon() 方法before 启动它或通过 isDaemon()
  • 检查它