一. java中的后台线程:
java线程大家都不陌生,可以用继承Thread类或者实现Runable接口来定义一个自己的线程。另外,java线程还可以分为前台线程(也称用户线程或普通线程)和后台线程(Daemon thread)。
1. 后台线程会随着主线程(main线程)的结束而结束,但是前台进程则不会(如果main线程先于前台进程结束,前台进程仍然会执行);或者说,只要有一个前台线程未退出,进程就不会终止。;
2. 默认情况下,程序员创建的线程是用户线程;用setDaemon(true)可以设置线程为后台线程;而用isDaemon( )则可以判断一个线程是前台线程还是后台线程;
3. jvm的垃圾回收器其实就是一个后台线程;
4. setDaemon函数必须在start函数之前设定,否则会抛出IllegalThreadStateException异常;
5.所有的“非后台线程”结束时,程序也就终止了,同时会杀死进程中所有后台线程:main就是一个非后台线程;
6.后台线程创建的子线程也是后台线程。
二、后台线程的实现:
importjava.util.concurrent.TimeUnit;public class DaemonDemo implementsRunnable {
@Overridepublic voidrun() {try{while (true) {
Thread.sleep(1000);
System.out.println("#" +Thread.currentThread().getName());
}
}catch(InterruptedException e) {
e.printStackTrace();
}finally {//后台线程不执行finally子句
System.out.println("finally ");
}
}public static voidmain(String[] args) {for (int i = 0; i < 10; i++) {
Thread daemon= new Thread(newDaemonDemo());//必须在start之前设置为后台线程
daemon.setDaemon(true);
daemon.start();
}
System.out.println("All daemons started");try{
TimeUnit.MILLISECONDS.sleep(1000);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:
All daemons started
#Thread-2
#Thread-3
#Thread-1
#Thread-0
#Thread-9
#Thread-6
#Thread-8
#Thread-5
#Thread-7
#Thread-4
分析:从结果可以看出,十个子线程并没有无线循环的打印,而是在主线程(main())退出后,JVM强制关闭所有后台线程。而不会有任何希望出现的确认形式,如finally子句不执行。
三、总结:
后台线程(daemon)
|——定义:指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分
| |——所有的“非后台线程”结束时,程序也就终止了,同时会杀死进程中所有后台线程:main就是一个非后台线程
|——声明并试用后台线程
| |——传统方式:通过声明线程,操作线程来定义后台线程
| | |——Thread daemon = new Thread(new TaskDaemon());//将任务交给线程也叫声明线程
| | |——daemon.setDaemon(true);//将线程设置为后台线程
| | |——daemon.start();//启动后台线程
| |——由executor调用线程工厂:通过编写定制的ThreadFactory,可以定制由Executor创建的线程的属性
| |——1.实现ThreadFactory接口
| |——2.重写newThread方法
| |——public Thread newThread(Runnable r){
| |——Thread t = new Thread(r);
| |——t.setDaemon(true);
| |——return t;
| |——}
| |——3.将定制的TaskDaemonFactory传递给Executor,它将用此来生成对应的线程,并操纵他们
| |——每个静态的ExecutorService创建方法都被重载为接受一个ThreadFactory对象,该对象将被用来创建新的线程
| |——ExecutorService exec = Executors.newCachedThreadPool(new TaskDaemonFactory());
| |——4.将任务传递给exec,它会帮你执行线程操作
| |——exec.execute(new TaskDaemonFromFactory());