守护进程线程与Java中的用户线程之间的区别?

一个线程用于在Jaa中执行并行执行,例如,在渲染屏幕中,程序也在后台从互联网上下载数据。Java中有两种类型的线程,用户线程和守护进程线程两者都可以用来实现Java中的并行处理,具体取决于任务的优先级和重要性。用户线程和守护进程线程之间的主要区别在于,只有当用户线程中的一个线程处于活动状态时,您的Java程序才会完成执行。JVM将等待所有活动的用户线程在其关闭之前完成其执行。另一方面,守护进程线程不会获得该优先级,JVM将退出并关闭Java程序即使在后台运行守护程序线程也是如此。它们在Java中被视为低优先级的线程,这就是为什么它们更适合非关键的后台作业。在这篇文章中,我们将从Java多线程和面试的角度来学习用户和守护线程之间的一些关键区别。

用户线程vs Java中的守护线程

正如我所说的,用户线程是您在日常编码中看到和使用的正常线程。您从主线程创建的任何线程都将成为用户线程。如果你想创建一个守护进程线程,那么你需要调用setDaemon(true)方法使其成为一个守护进程。

另一个要记住的关键是,从守护线程产生的任何新线程也成为守护进程,因为线程从创建守护进程的线程继承它们的守护进程属性。由于主线程是非守护线程,所以从主生成的任何线程也变为非守护进程或用户线程。

我们来看看Java中用户和守护进程之间的差别。


1)JVM不等待守护线程完成 
首要的区别是JVM不会等待守护线程完成他们的工作,但它将等待任何活动的用户线程。在Eclipse中运行Java程序时,您可能已经注意到这种行为,即使您的主线程已经完成了右上角的按钮,仍然是红色的,表明Java程序仍在运行。这是由于从主线程产生的任何用户线程,但主要的是你在Eclipse中看不到那个红点。

以下是Eclipse中的代码片段,它演示了:

2)JVM本身创建守护进程thrad守护进程的 
另一个区别是守护进程线程主要是由JVM创建的,比如一些垃圾收集工作。另一方面,用户线程通常由应用程序创建,用于同时执行某个任务。您还可以查看  Java性能权威指南以了解有关JVM在关机期间执行的操作的更多信息。


3)守护线程不用于关键任务 
守护进程和用户线程的另一个主要区别是守护进程不用于任何关键任务。任何重要的任务都是由非守护进程或用户线程完成的。守护线程通常用于一些不重要的后台任务。


4)线程优先 

与用户线程相比,守护线程是低优先级的线程。这意味着他们不会像用户线程那样容易获得CPU。请参阅Java Thread第3版以了解有关线程优先级和线程间CPU分配情况的更多信息。


5)JVM关闭守护进程线程
用户线程被应用程序或其本身关闭,但如果所有的用户线程完成执行,JVM将强制守护线程终止。守护进程线程无法保持JVM运行,但用户线程可以。这是守护进程和用户线程之间最重要的区别,您应该记住这一点。


Java程序来创建守护线程

这里是我们的示例Java程序来演示Java中的守护进程和用户线程之间的真正区别。它还告诉你如何用Java创建一个守护进程线程,或者如何通过调用Java中的setDaemon(true)来建立一个正常的线程守护进程。默认情况下,从主线程创建的任何线程都是非守护进程或用户线程。


/**
 * Java程序来演示守护进程和用户线程之间的区别。
 * 这个程序还告诉你如何在Java中创建一个线程守护进程。
 * 
 */
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        // 主线程是一个非守护进程线程
        String name = Thread.currentThread().getName();
        boolean isDaemon = Thread.currentThread().isDaemon();
        System.out.println("name: " + name + ", isDaemon: " + isDaemon);
        //从main派生的任何新线程也是非守护进程或用户线程
        //如下所示:
        Runnable task = new Task();
        Thread t1 = new Thread(task, "T1");
        System.out.println("线程从主线程中产生");
        System.out.println("name: " + t1.getName() + ", isDaemon: " + t1.isDaemon());
        //尽管你可以通过调用setDaemon()来创建一个守护线程,
        //如下所示:
        t1.setDaemon(true);
        t1.start();
        // 让我们等待T1完成
        t1.join();
    }
    private static class Task implements Runnable {
        @Override public void run() {
            Thread t = Thread.currentThread();
            System.out.println("线程通过调用守护进程 setDaemon() 方法");
            System.out.println("name: " + t.getName() + ", isDaemon: " + t.isDaemon());
            //守护线程创建的任何新线程也是守护进程
            Thread t2 = new Thread("T2");
            System.out.println("线程从守护线程产生");
            System.out.println("name: " + t2.getName() + ", isDaemon: " + t2.isDaemon());
        }
    }

}
控制台输出:

name: main, isDaemon: false

线程从主线程中产生

name: T1, isDaemon: false

线程通过调用守护进程 setDaemon() 方法

name: T1, isDaemon: true线程从守护线程产生

name: T2, isDaemon: true

这就是守护进程和Java中的非守护线程之间区别。记住JVM将强制终止所有活动的守护进程线程(如果没有用户线程正在等待执行或处于活动状态),所以不要在守护进程线程上执行任何关键任务。

另外,请记住,该线程从创建它的线程继承守护进程属性。例如,如果你从main()产生一个新的线程,那么它们将是非守护进程或用户线程,而你需要调用setDaemon(true)来使它们守护进程,另一方面,如果你从一个新的线程产生一个新的线程一个守护进程线程然后默认情况下它将是一个守护进程线程。


关于“ 守护进程线程与Java中的用户线程之间的区别? 的评论

发表评论