java前台线程和后台线程

一.  java中的后台线程:

      java线程大家都不陌生,可以用继承Thread类或者实现Runable接口来定义一个自己的线程。另外,java线程还可以分为前台线程(也称用户线程或普通线程)和后台线程(Daemon thread)。

     1.  后台线程会随着主线程(main线程)的结束而结束,但是前台进程则不会(如果main线程先于前台进程结束,前台进程仍然会执行);或者说,只要有一个前台线程未退出,进程就不会终止。;

     2.  默认情况下,程序员创建的线程是用户线程;用setDaemon(true)可以设置线程为后台线程;而用isDaemon( )则可以判断一个线程是前台线程还是后台线程;

     3. jvm的垃圾回收器其实就是一个后台线程;

     4. setDaemon函数必须在start函数之前设定,否则会抛出IllegalThreadStateException异常;

  5.所有的“非后台线程”结束时,程序也就终止了,同时会杀死进程中所有后台线程:main就是一个非后台线程;

    6.后台线程创建的子线程也是后台线程。

二、后台线程的实现:

 

import java.util.concurrent.TimeUnit;  
  
public class DaemonDemo implements Runnable {  
    @Override  
    public void run() {  
        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 void main(String[] args) {  
        for (int i = 0; i < 10; i++) {  
            Thread daemon = new Thread(new DaemonDemo());  
            // 必须在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());

原文地址:https://www.cnblogs.com/hejing-swust/p/8038359.html