您的位置:首页 > 编程语言 > Java开发

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

2013-05-11 09:47 591 查看
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次运行.....

用户线程退出.....

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: