在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)
用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守护线程的保姆:
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。
User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果 User Thread已经全部退出运行了,只剩下Daemon Thread存在了,虚拟机也就退出了。 因为没有了被守护者,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。
守护线程并非只有虚拟机内部提供,用户在编写程序时也可以自己设置守护线程。下面的方法就是用来设置守护线程的。
Thread daemonTread = new Thread();
// 设定 daemonThread 为 守护线程,default false(非守护线程)
daemonThread.setDaemon(true);
// 验证当前线程是否为守护线程,返回 true 则为守护线程
daemonThread.isDaemon();
这里有几点需要注意:
(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
(2) 在Daemon线程中产生的新线程也是Daemon的。
(3) 不要认为所有的应用都可以分配给Daemon来进行服务,比如读写操作或者计算逻辑。
因为你不可能知道在所有的User完成之前,Daemon是否已经完成了预期的服务任务。一旦User退出了,可能大量数据还没有来得及读入或写出,计算任务也可能多次运行结果不一样。这对程序是毁灭性的。造成这个结果理由已经说过了:一旦所有User Thread离开了,虚拟机也就退出运行了。
下面我们写两个测试用例分别测试这两种线程
package org.bird.daemon;
public class MyThread extends Thread {
public void run() {
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("线程名称:" + Thread.currentThread().getName() + "正在运行...");
}
}
}
首先写一个用户线程测试场景
package org.bird.daemon;
public class UserThread {
/**
* @param args
*/
public static void main(String[] args) {
Thread t = new MyThread();
t.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("退出jvm");
}
});
}
}
测试结果:
通过测试结果我们发现主线程运行完成后,线程MyThread继续运行,JVM并没有退出。
再写一个守护线程测试场景
package org.bird.daemon;
public class DaemonThread {
/**
* @param args
*/
public static void main(String[] args) {
Thread t = new MyThread();
t.setDaemon(true);
t.start();
for(int i = 0; i < Integer.MAX_VALUE; i++) {
}
}
}
测试结果:
通过测试结果我们发现主线程运行完成后,线程MyThread停止,JVM退出。
为什么要用守护线程?
我们知道静态变量是ClassLoader级别的,如果Web应用程序停止,这些静态变量也会从JVM中清除。但是线程则是JVM级别的,如果你在Web 应用中启动一个线程,这个线程的生命周期并不会和Web应用程序保持同步。也就是说,即使你停止了Web应用,这个线程依旧是活跃的。正是因为这个很隐晦的问题,所以很多有经验的开发者不太赞成在Web应用中私自启动线程。
- 大小: 11.2 KB
- 大小: 10.4 KB
分享到:
相关推荐
Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-...
Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 ...
java daemon 程序,有助于理解守护线程的概念和使用
Java线程:线程的调度-守护线程 28 Java线程:线程组 30 Java线程:线程的同步 33 一、 同步方法 35 二、 同步块 36 三、 volatile关键字 38 四、 使用synchronized关键字要注意以下四点 39 五、 关于同步和锁定的...
很多人对java的线程不是很了解,甚至连守护线程都么有听过,其实很简单,守护线程就是普通的线程,区别再于,他就是类似一个秘书一样,记录着所有的非守护线程的信息等等,守护线程,是指为工作线程做相关统计、汇总...
Java线程:线程的调度-守护线程 Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 ...
主要介绍了浅谈java的守护线程与非守护线程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
如果你想使用Java,就必须学习线程。 本书的新版本展示了如何利用Java线程工具的全部优势,并介绍了JDK 2线程接口中的最新变化。你将学习如何使用线程来提高效率,如何有效地使用它们,以及如何避免常见的错误。...
Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 ...9.11 守护线程
守护线程使用的注意事项总结 什么是Java的守护线程( Daemon Thread )? Java 提供了两种类型的线程:守护线程 和 用户线程 用户线程 (User Thread) 是高优先级线程。JVM 会在终止之前等待任何用户线程完成其任务。 ...
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 。下面通过本文给大家分享java守护线程实例详解,需要的朋友参考下吧
精灵线程(Daemon)或守护线程---马克-to-win java视频
主要介绍了java守护线程与非守护线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Java多线程核心技术:理解多线程、在Java中实现多线程、线程的生命周期、线程的优先级、线程的同步、线程的阻塞、守护线程、线程组、线程池、总结。
java 变形金刚中的守护神(守护线程) java 变形金刚中的守护神(守护线程) java 变形金刚中的守护神(守护线程)
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 作用 Daemon的作用是为其他线程的运行提供便利服务,守护线程典型的应用是 GC (垃圾回收器),它是一个很称职的守护者。 区别 ...
Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,...一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。 多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。
本篇文章主要介绍了浅谈java中守护线程与用户线程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧