关于多线程:Java中的守护程序线程是什么?

What is a daemon thread in Java?

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


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

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


更多的要点(参考:实践中的Java并发)

  • 创建新线程时,它会继承其起源。
  • 当所有非守护进程线程完成时,jvm将停止,并放弃所有剩余的守护进程线程:

    • 最后,不执行块,
    • 堆栈没有展开-JVM只是退出。

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


以上答案都很好。下面是一个简单的代码片段,用来说明不同之处。用setDaemon中的每一个"真"和"假"值进行尝试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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将退出。您可以通过在Thread上调用setDaemon()方法来创建一个。

读取守护进程线程。


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

例如,hotjava浏览器最多使用四个名为"image fetcher"的守护进程线程从文件系统或网络中获取需要的任何线程的图像。

守护进程线程通常用于为应用程序/小程序执行服务(例如加载"fiddley位")。用户线程和守护进程线程之间的核心区别在于,只有在所有用户线程都已终止时,JVM才会关闭程序。当不再有任何用户线程(包括执行的主线程)运行时,jvm将终止守护进程线程。

setdaemon(对/错)?此方法用于指定线程是守护进程线程。

公共布尔isDaemon()?此方法用于确定线程是否为守护进程线程。

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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");
    }

}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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>

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

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

您可以使用setDaemon方法指定Thread是一个守护进程,它们通常不退出,也不中断。它们只是在应用程序停止时停止。


守护进程定义(计算):

A background process that handles requests for services such as print spooling and file transfers, and is dormant when not required.

--资料来源:牛津词典英文版

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

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


我想澄清的一个误解是:

  • 假设守护进程线程(比如b)是在用户线程(比如a);则此用户线程/父线程的结束(a)不会结束它创建的守护进程线程/子线程(B);前提是只有用户线程一个正在运行。
  • 所以线程结束时没有父子关系。一旦没有单个活动用户线程并且导致JVM终止,所有守护进程线程(无论创建在何处)都将结束。
  • 即使这两个(父/子)都是守护进程线程。
  • 如果子线程是从守护进程线程创建的,那么它也是一个守护进程线程。这不需要任何显式的守护进程线程标志设置。类似地,如果一个子线程是从一个用户线程创建的,那么它也是一个用户线程,如果您想更改它,那么在该子线程开始之前需要显式的守护进程标志设置。


Java有一种特殊类型的线程称为守护进程线程。

  • 优先级很低。
  • 仅在同一程序没有其他线程运行时执行。
  • 当守护进程线程程序中唯一运行的线程。

守护进程线程的用途是什么?

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

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

还有更多…

  • 在调用start()方法之前,只调用setDaemon()方法。一旦线程运行,就不能修改其守护进程状态。
  • 使用isDaemon()方法检查线程是守护进程线程还是用户线程。


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


守护进程线程类似于助手。非守护进程线程类似于前执行者。助手帮助表演者完成工作。当作业完成后,执行者不再需要帮助来执行任务。由于不需要帮助,助手们离开了这个地方。因此,当非守护进程线程的作业结束时,守护进程线程将逐渐消失。


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


Java中的守护线程是在后台运行的线程,主要由JVM创建,用于执行后台任务,如垃圾回收和其他维护任务。

注意事项:

  • 在Java中运行main方法的任何线程都是默认的非守护进程,因为线程从创建父线程的线程继承它的守护进程性质,并且因为主线程是非守护进程线程,所以通过调用StaDaMeMon(true),直到显式地生成守护进程为止,从它创建的任何其他线程都将保持非守护进程。

  • 线程。StAdEimon(True)创建线程守护进程,但只能在Java中启动线程之前调用它。如果相应的线程已经启动并运行,它将抛出IllegalThreadStateException。

  • Java中守护进程与非守护进程线程的区别

    1)jvm不会等待任何守护进程线程在存在之前完成。

    2)当jvm终止时,守护进程线程的处理方式与用户线程不同,最后不调用块,堆栈不接地,jvm只退出。


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

    要添加这个守护进程线程可以在假设我提供API(比如将数据推送到第三方服务器/或JMS)时使用,我可能需要在客户端JVM级别聚合数据,然后在单独的线程中发送给JMS。我可以将这个线程设置为守护进程线程,如果这不是强制将数据推送到服务器上的话。这种数据类似于日志推送/聚合。

    当做,曼尼什


    守护进程线程就像守护进程,负责管理资源,后台线程由Java VM创建,以服务用户线程。Unix的更新系统示例,Unix是守护进程。守护进程线程的子级始终是守护进程线程,因此默认情况下,守护进程为false。您可以使用"is daemon()"方法检查线程作为守护进程或用户。所以守护进程线程或守护进程基本上负责管理资源。例如,当您启动JVM时,运行的垃圾收集器是守护进程线程,其优先级为1(最低),这是管理内存。只要用户线程是活动的,就不能终止守护进程线程。jvm负责终止守护进程线程。


    在爪哇中,守护线程是线程的一种类型,它不能阻止Java虚拟机(JVM)退出。守护进程线程的主要目的是执行后台任务,特别是在某些例行的定期任务或工作的情况下。有了jvm出口,守护进程线程也会死。

    通过设置一个thread.setDaemon(true),一个线程就变成了一个守护进程线程。但是,只能在线程启动之前设置此值。


    守护进程线程通常称为"服务提供程序"线程。这些线程不应该用于执行程序代码,而应该用于系统代码。这些线程与代码并行运行,但JVM可以随时杀死它们。当jvm找不到用户线程时,它会停止它,所有守护进程线程都会立即终止。我们可以使用以下方法将非守护进程线程设置为守护进程:

    1
    setDaemon(true)


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

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

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


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

    更多参考:Java中的守护进程线程


    对我来说,守护进程线程就像是用户线程的管理员。如果所有用户线程都已完成,则守护进程线程没有作业,并且被JVM杀死。我在YouTube视频中解释过。


    让我们只用代码和工作示例来讨论。我喜欢上面的Russ的回答,但为了消除我的疑虑,我稍微加强了一点。我运行了两次,一次将工作线程设置为deamon true(deamon线程),另一次将其设置为false(用户线程)。它确认当主线程终止时,deamon线程结束。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    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

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


    下面是一个测试守护进程线程行为的示例,以防由于不存在用户线程而退出JVM。

    请注意下面输出的最后一行,当主线程退出时,守护进程线程也会停止,并且没有在finally块中打印finally executed9语句。这意味着,如果由于不存在用户线程而退出JVM,那么在守护进程线程finally块内关闭的任何I/O资源都不会关闭。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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");
      }
    }

    产量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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

    当创建者线程退出时,守护进程线程将死亡。

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

    1
    2
    3
    4
    if ( threadShouldDieOnApplicationEnd ) {
        thread.setDaemon ( true );
    }
    thread.start();