java守护进程 - Java中的守护进程是什么?




multithreading (16)

任何人都可以告诉我Java中的守护线程是什么?


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

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

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

注意事项:

  1. 由主线程创建的任何线程(在Java中运行主方法)都是默认的非守护进程,因为线程会从创建它的线程继承它的守护进程性质,即父线程,并且由于主线程是非守护线程,所以从其创建的任何其他线程都会直到通过调用setDaemon(true)进行明确的守护进程才保持非守护进程。

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

Java中守护进程和非守护进程之间的区别:

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

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


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

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

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


以上所有答案都很好。 这里有一个简单的小代码片段,来说明不同之处。 在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
            }
        }
    }
}

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

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


在Java中, 守护进程线程是不阻止Java虚拟机(JVM)退出的线程类型之一。 守护线程的主要目的是执行后台任务,特别是在一些例行的定期任务或工作的情况下。 使用JVM退出时,守护进程线程也会死亡。

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


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

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

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

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


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

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

守护进程线程通常用于为您的应用程序/ applet执行服务(例如,加载“fiddley比特”)。 用户线程和守护进程线程的核心区别在于,当所有用户线程终止时,JVM只会关闭一个程序。 当不再有任何用户线程运行时,守护程序线程将由JVM终止,包括主线程的执行。

setDaemon(true / false)? 这个方法用来指定一个线程是守护线程。

公共布尔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>

守护进程线程就像大家所说的那样,不会约束JVM退出,所以基本上它是一个从退出的角度来看Application的快乐线程。

想要添加守护进程线程可以用于说我提供的API像推送数据到第三方服务器/或JMS,我可能需要在客户端JVM级别聚合数据,然后发送到JMS在一个单独的线程。 如果这不是强制数据被推送到服务器,我可以使这个线程作为守护进程线程。 这种数据就像日志推送/聚合。

问候,马尼什


守护进程线程就像负责管理资源的守护进程一样,守护进程线程由Java VM创建以服务用户线程。 示例更新系统为unix,unix是守护进程。 守护线程的子节点总是守护线程,所以默认情况下守护进程为false。你可以使用“isDaemon()”方法检查线程是守护进程还是用户。 所以守护进程线程或守护进程基本上负责管理资源。 例如,当您启动jvm时,运行的垃圾收集器即守护进程线程,其优先级为1,最低的是管理内存。 只要用户线程处于活动状态,jvm就处于活动状态,并且不能终止守护进程。线程负责终止守护进程线程。


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

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


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


我想澄清一个误解:

  • 假设守护线程(如B)在用户线程内创建(如A); 那么这个用户线程/父线程(A)的结束将不会结束它创建的守护线程/子线程(B); 提供的用户线程是当前正在运行的唯一一个。
  • 所以在线程结束时没有父子关系。 一旦没有单个活动用户线程并且导致JVM终止,所有守护进程线程(不管它在哪里创建)都将结束。
  • 即使这对于(父/子)都是守护线程也是如此。
  • 如果从守护线程创建子线程,那么这也是一个守护线程。 这将不需要任何显式的守护进程线程标志设置。 同样,如果从用户线程创建的子线程也是用户线程,如果要更改它,则在该子线程开始之前需要显式守护进程标志设置。

还有几点(参考: 实践中的Java并发

  • 当一个新线程被创建时,它会继承其父进程的守护进程状态。
  • 普通线程和守护进程线程在退出时会发生什么变化。 当JVM暂停任何剩余的守护进程线程时

    • 最后块不会被执行
    • 堆栈没有解开 - JVM刚刚退出。

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


这里是一个例子,用于在由于用户线程不存在而导致jvm退出的情况下,测试守护线程的行为。

请注意下面输出中的第二行,当主线程退出时,守护进程线程也会死亡,并且不会在finally块内打印最终执行的语句。 这意味着,如果由于用户线程不存在而导致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




multithreading