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

         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次运行.....
用户线程退出.....

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

 
 
 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值