首先明白知识点:
Java有两种Thread:“守护线程Daemon”与“用户线程User”。
守护线程是一种“在后台提供通用性支持”的线程,它并不属于程序本体。
从字面上我们很容易将守护线程理解成是由虚拟机(virtual machine)在内部创建的,而用户线程则是自己所创建的。事实并不是这样,任何线程都可以是“守护线程Daemon”或“用户线程User”。他们在几乎每个方面都是相同的,唯一的区别是判断虚拟机何时离开:
用户线程:Java虚拟机在它所有非守护线程已经离开后自动离开。
守护线程:守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。
setDaemon(boolean on)方法可以方便的设置线程的Daemon模式,true为Daemon模式,false为User模式。isDaemon方法将测试该线程是否为守护线程。
这里有几点需要注意:
(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
(2) 在Daemon线程中产生的新线程也是Daemon的。
(3) 不要认为所有的应用都可以分配给Daemon来进行服务,比如读写操作或者计算逻辑。
然后讲示例:
下面代码,我标记注释处的两个地方,
第一种情况:
当我把那两行注释掉时,运行程序程序无法结束,要用Ctrl+c才能终止
这种情况下,主程序已经运行完了,可以看到结果over打印出来了,但是线程并没有结束!所以整个程序还在运行,需要强制结束!
第二种情况:
当我把那两行代码取消注释,运行程序,发现程序自己就能结束了。
为什么?
因为把t1,t2设置成守护线程了!设置成守护线程,在主方法运行结束后(主方法就是用户线程,用户线程又叫非守护线程!),除了守护线程没有任何线程还在运行了,守护线程没有服务的对象,作为一个守护线程此时会自己结束。看上面的知识点说(如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。),
- class StopThread implements Runnable
- {
- private boolean flag =true;
- public synchronized void run()
- {
- while(flag)
- {
- try
- {
- wait();
- }
- catch (Exception e)
- {
- System.out.println(Thread.currentThread().getName()+"....Exception");
- }
-
- System.out.println(Thread.currentThread().getName()+"....run");
- }
- }
- public void changeFlag()
- {
- flag = false;
- }
- }
- class StopThreadDemo
- {
- public static void main(String[] args)
- {
- StopThread st = new StopThread();
-
- Thread t1 = new Thread(st);
- Thread t2 = new Thread(st);
- t1.setDaemon(true); //注释处!!!
- t2.setDaemon(true); //注释处!!!
- t1.start();
- t2.start();
- int num = 0;
- while(true)
- {
- if(num++ == 60)
- {
- break;
- }
- System.out.println(Thread.currentThread().getName()+"......."+num);
- }
- System.out.println("over");
- }
- }
复制代码
|