JAVA用户线程&守护线程的区别

来源:互联网 发布:郎酒 知乎 编辑:程序博客网 时间:2024/05/01 19:22

         JAVA中线程可分为:用户线程(普通线程)、守护线程(后台线程)。

   

       

        所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。
 
  用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

 

       那怎样让一个用户线程成为守护线程呢?翻看Thread类的API,发现有一个setDaemon(boolean on)方法。我们进去看看源码及描述。

/**     * Marks this thread as either a daemon thread or a user thread. The      * Java Virtual Machine exits when the only threads running are all      * daemon threads.      * <p>     * This method must be called before the thread is started.       * <p>     * This method first calls the <code>checkAccess</code> method      * of this thread      * with no arguments. This may result in throwing a      * <code>SecurityException </code>(in the current thread).     *     * @param      on   if <code>true</code>, marks this thread as a     *                  daemon thread.     * @exception  IllegalThreadStateException  if this thread is active.     * @exception  SecurityException  if the current thread cannot modify     *               this thread.     * @see        #isDaemon()     * @see        #checkAccess     */    public final void setDaemon(boolean on) {checkAccess();if (isAlive()) {    throw new IllegalThreadStateException();}daemon = on;    }

      

       通过这方法,我们可以决定该线程是守护线程呢还是用户线程。如果正在运行的线程全部都是守护线程(用户线程全部退出了),则JVM就会退出。如果要把一个线程设置为守护线程,则必须在它启动前,调用该方法进行设置(看源码也可以看出来,if(isAlive)就抛出异常)。

      平时的项目开发中,很少使用守护线程,因为JVM退出,它也会强制结束了。下面给个例子,简单模拟下,用户线程退出了,守护线程就算没执行完,JVM也会退出。

package daemon;/** * 当所有用户线程(也就普通线程)都已退出,只剩下守护线程时 * JVM会退出,守护线程也会被kill掉 *(主要还有一个普通线程在运行,JVM就不会退出) */public class DeamonThreadTest {public static void main(String[] args) {//创建一个用户线程Thread userThread=new Thread(){public void run(){for(int i=1;i<=5;i++){try {Thread.sleep(200);System.out.println("用户线程第"+i+"次运行.....");} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("用户线程退出.....");}};//创建一个用户模拟守护线程的线程Thread daemonThread=new Thread(){public void run(){for(int i=1;i<=99999;i++){try {Thread.sleep(50);System.out.println("守护线程第"+i+"次运行.....");} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("守护线程退出.....");}};//让daemonThread成为守护线程daemonThread.setDaemon(true);//这里必须在启动前设置,如果不设置,默认人是用户线程userThread.start();daemonThread.start();}}

运行结果

守护线程第1次运行.....
守护线程第2次运行.....
守护线程第3次运行.....
用户线程第1次运行.....
守护线程第4次运行.....
守护线程第5次运行.....
守护线程第6次运行.....
守护线程第7次运行.....
用户线程第2次运行.....
守护线程第8次运行.....
守护线程第9次运行.....
守护线程第10次运行.....
守护线程第11次运行.....
用户线程第3次运行.....
守护线程第12次运行.....
守护线程第13次运行.....
守护线程第14次运行.....
守护线程第15次运行.....
用户线程第4次运行.....
守护线程第16次运行.....
守护线程第17次运行.....
守护线程第18次运行.....
守护线程第19次运行.....
用户线程第5次运行.....
用户线程退出.....

    可以看到,用户线程会执行完全部步骤,而守护线程呢,只是执行了一部分。

   

 

 

 

原创粉丝点击