这里有新鲜出炉的 Java 函数式编程,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要介绍了浅谈 java 的守护线程与非守护线程,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧
最近重新研究 Java 基础知识,发现以前太多知识知识略略带过了,比较说 Java 的线程机制,在 Java 中有两类线程:User Thread(用户线程),Daemon Thread(守护线程) ,(PS: 以前忽略了).
估计学过 Unix 开发但是没有细致学习 Java 的同学们会疑惑了,操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是 Java 语言机制是构建在 JVM 的基础之上的,意思是 Java 平台把操作系统的底层给屏蔽起来,所以它可以在它自己的虚拟的平台里面构造出对自己有利的机制,而语言或者说平台的设计者多多少少是收到 Unix 思想的影响,而守护线程机制又是对 JVM 这样的平台凑合,于是守护线程应运而生.
Daemon 的作用是为其他线程的运行提供服务,比如说 GC 线程.其实 User Thread 线程和 Daemon Thread 守护线程本质上来说去没啥区别的,唯一的区别之处就在虚拟机的离开:如果 User Thread 全部撤离,那么 Daemon Thread 也就没啥线程好服务的了,所以虚拟机也就退出了.
守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:public final void setDaemon(boolean on) ;但是有几点需要注意:
1),thread.setDaemon(true) 必须在 thread.start() 之前设置,否则会跑出一个 IllegalThreadStateException 异常.你不能把正在运行的常规线程设置为守护线程. (备注:这点与守护进程有着明显的区别,守护进程是创建后,让进程摆脱原会话的控制 + 让进程摆脱原进程组的控制 + 让进程摆脱原控制终端的控制;所以说寄托于虚拟机的语言机制跟系统级语言有着本质上面的区别)
2), 在 Daemon 线程中产生的新线程也是 Daemon 的. (这一点又是有着本质的区别了:守护进程 fork() 出来的子进程不再是守护进程,尽管它把父进程的进程相关信息复制过去了,但是子进程的进程的父进程不是 init 进程,所谓的守护进程本质上说就是" 父进程挂掉,init 收养,然后文件 0,1,2 都是 / dev/null,当前目录到 /")
3),不是所有的应用都可以分配给 Daemon 线程来进行服务,比如读写操作或者计算逻辑.因为在 Daemon Thread 还没来的及进行操作时,虚拟机可能已经退出了.
例子:
运行结果:文件 daemon.txt 中没有 "daemon" 字符串.
//完成文件输出的守护线程任务
import java.io. * ;
class TestRunnable implements Runnable {
public void run() {
try {
Thread.sleep(1000); //守护线程阻塞1秒后运行
File f = new File("daemon.txt");
FileOutputStream os = new FileOutputStream(f, true);
os.write("daemon".getBytes());
} catch(IOException e1) {
e1.printStackTrace();
} catch(InterruptedException e2) {
e2.printStackTrace();
}
}
}
public class TestDemo2 {
public static void main(String[] args) throws InterruptedException {
Runnable tr = new TestRunnable();
Thread thread = new Thread(tr);
thread.setDaemon(true); //设置守护线程
thread.start(); //开始执行分进程
}
}
但是如果把 thread.setDaemon(true); // 设置守护线程注释掉,文件 daemon.txt 是可以被写入 daemon 字符串的
JRE 判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台线程候一定要注意这个问题.
但是 daemon Thread 实际应用在那里呢?举个例子,web 服务器中的 Servlet,容器启动时后台初始化一个服务线程,即调度线程,负责处理 http 请求,然后每个请求过来调度线程从线程池中取出一个工作者线程来处理该请求,从而实现并发控制的目的.
网上摘的一个图,方便大家理解:
来源: http://www.phperz.com/article/18/0117/353034.html