守护(Daemon)线程的创建及运行

1、守护(Daemon)线程简介

在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程或服务线程) 。任何一个守护线程都是整个JVM中所有非守护线程的保姆,守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务。

通过setDaemon(true)来设置线程为“守护线程”;将一个用户线程设置为守护线程的方式是在thread.start()之前用线程对象的setDaemon方法。

只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。

Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),当我们的程序中不再有任何运行的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是JVM上仅剩的线程时,垃圾回收线程会自动离开。它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。

User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果 User Thread已经全部退出运行了,只剩下Daemon Thread存在了,虚拟机也就退出了。 因为没有了被守护者,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。那Java的守护线程是什么样子的呢。当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则JVM不会退出。

守护线程并非只有虚拟机内部提供,用户在编写程序时也可以自己设置守护线程。

2、代码事例

package com.xxx.util;

import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-30
 * Time: 上午9:02
 * To change this template use File | Settings | File Templates.
 */
public class DaemonEntity {
    private Date date;
    private String event;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getEvent() {
        return event;
    }

    public void setEvent(String event) {
        this.event = event;
    }
}
package com.xxx.util;

import java.util.Date;
import java.util.Deque;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-30
 * Time: 上午9:06
 * To change this template use File | Settings | File Templates.
 */
public class ThreadUser implements Runnable {

    private Deque<DaemonEntity> deque;

    public ThreadUser(Deque<DaemonEntity> deque){
        this.deque = deque;
    }

    @Override
    public void run() {
        for(int i=1;i<100;i++){
            DaemonEntity daemonEntity = new DaemonEntity();
            daemonEntity.setDate(new Date());
            daemonEntity.setEvent(String.format("The thread %s has generated an event\n",Thread.currentThread().getId()));
            deque.addFirst(daemonEntity);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.xxx.util;

import java.util.Date;
import java.util.Deque;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-30
 * Time: 上午9:24
 * To change this template use File | Settings | File Templates.
 */
public class ThreadDaemon extends Thread {

    private Deque<DaemonEntity> deque;

    public ThreadDaemon(Deque<DaemonEntity> deque){
        this.deque = deque;
        setDaemon(true);//设置为守护线程
    }

    @Override
    public void run(){
        while (true){
            Date date = new Date();
            cleanDeque(date);
        }
    }

    public void cleanDeque(Date date){
        long difference;
        boolean deleteFlag;
        if(deque.size()==0){
            return;
        }
        deleteFlag = false;
        do{
            DaemonEntity daemonEntity = deque.getLast();
            difference = date.getTime()- daemonEntity.getDate().getTime();
            if(difference>10000){
                System.out.printf("Cleaner: size of the queue:%d\n",deque.size());
                deque.removeLast();
                deleteFlag = true;
            }
        }while (difference>10000);
        if(deleteFlag){
            System.out.printf("Cleaner: size of the queue:%d\n",deque.size());
        }
    }

}
package com.xxx.util;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * Created with IntelliJ IDEA.
 * Date: 15-3-30
 * Time: 上午9:38
 * To change this template use File | Settings | File Templates.
 */
public class ThreadDaemonMain {

    public static void main(String[] args){
        Deque<DaemonEntity> deque = new ArrayDeque<DaemonEntity>();
        ThreadUser threadUser = new ThreadUser(deque);
        for(int i=0;i<3;i++){
            Thread thread = new Thread(threadUser);
            thread.start();
        }
        ThreadDaemon threadDaemon = new ThreadDaemon(deque);
        threadDaemon.start();
    }

}
3、运行结果:


4、结论

守护线程在用户线程休眠时进行了删除操作,如果休眠时间越小,队列长度将增加,如果用户线程不休眠,守护线程没有删除对象就结束了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值