博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
守护线程的创建和运行
阅读量:6495 次
发布时间:2019-06-24

本文共 3222 字,大约阅读时间需要 10 分钟。

  hot3.png

Java里有一种特殊的线程叫做守护(daemon)线程。这种线程的优先级很低,通常来说,当同一个应用程序里没有其它的线程运行的时候,守护线程才运行。当守护线程是程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个程序。

因为这种特性,守护线程通常被用来做为同一程序中普通线程(也称为用户线程)的服务提示者。它们通常是无限循环的,以等待服务请求或执行线程的任务。它们不能做重要的工作,因为我们不可能知道守护线程什么时候能够获取CPU时钟,并且,在没有其他线程运行的时候,守护线程随时可能结束。一个典型的守护线程是java的垃圾回收器(Garbage Collector)。

范例程序包含两个线程:一个是用户线程,它将事件写入到一个队列中;另一个是守护线程,它将管理这个队列,如果生成的事件超过10秒钟,就会被移除。

package concurrency;import java.util.Date;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.TimeUnit;public class Main1 {    public static void main(String[] args) {        LinkedBlockingDeque
 deque = new LinkedBlockingDeque
();        WriterTask writer = new WriterTask(deque);        for(int i = 0;i < 3; i++){            Thread thread = new Thread(writer);            thread.start();        }        CleanerTask cleaner = new CleanerTask(deque);        cleaner.start();    }}class Event{    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;    }}class WriterTask implements Runnable{    private LinkedBlockingDeque
 deque;    public WriterTask(LinkedBlockingDeque
 deque){        this.deque = deque;    }    public void run() {        for(int i = 1; i <= 20; i++){            Event event = new Event();            event.setDate(new Date());            event.setEvent(String.format("The thread %s has generated an event",                 Thread.currentThread().getId()));            deque.addFirst(event);            try {                TimeUnit.SECONDS.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}class CleanerTask extends Thread{    private LinkedBlockingDeque
 deque;    public CleanerTask(LinkedBlockingDeque
 deque){        this.deque = deque;        this.setDaemon(true);    }    @Override    public void run() {        while(true){            Date date = new Date();            clean(date);        }    }    private void clean(Date date){        long difference;        boolean delete;        if(deque.size() == 0) return;        delete = false;        do {            Event e = deque.getLast();            difference = date.getTime() - e.getDate().getTime();            if(difference > 10000){                System.out.printf("Cleaner: %s\n", e.getEvent());                deque.removeLast();                delete = true;            }        } while (difference > 10000);        if(delete){            System.out.printf("Cleaner: Size of the queue : %d\n", deque.size());        }    }}

对程序的运行输出进行分析之后,我们会发现,队列中的对象会不断增长直到30个,然后到程序结束,队列的长度维持在27~30之间。

这个程序有3个WriterTask线程,每个线程向队列写入一个事件,然后休眠1秒钟。在第一个10秒钟内,队列中有30个事件,直到3个WriterTask都休眠后,CleanerTask才开始执行,但是它没有删除任何事件。因为所有的事件都小于10秒钟。在接下来的运行中,CleanerTask每秒删除3个对象,同时WriterTask会写入3个对象,所以队列的长度一直介于27~30之间。

setDaemon()方法只能在start()方法被调用之前设置。一旦线程开始运行,将不能再修改守护状态。isDaemon()方法被用来检查一个线程是不是守护线程,返回值true,表示这个线程是守护线程; false表示这个线程是用户线程。

注意:1. thread.setDaemon(true)必须在thread.start()之前设置。2. 在Daemon线程中产生的新线程也是Daemon的。新创建一个新Thread对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护线程。3. 当用户线程(非守护线程)全部结束,则守护线程也随即结束,否则守护线程将一直执行(不管你的守护线程业务逻辑是不是while(true)这样的死循环)。

转载于:https://my.oschina.net/fhd/blog/406134

你可能感兴趣的文章
NPM 模块收集
查看>>
ReactNative 环境的搭建和启动(安卓版)
查看>>
DEX文件的签名和校验(翻译)
查看>>
Silverlight显示数据库二进制字段图片(RadTileView)
查看>>
斯坦福大学机器学习第六课“逻辑回归(Logistic Regression)”
查看>>
《坦克世界》1.0+:使用 CPU 优化的图形和物理丰富用户体验
查看>>
【Udacity】解决:字幕遮挡视频内容怎么办?Udacity字幕大小调整
查看>>
POJ 1159, Palindrome
查看>>
Java并发之AQS详解
查看>>
锐捷网络笔试分享—应用软件开发
查看>>
HDFS架构剖析
查看>>
在IOS中使用json
查看>>
Orlion个人博客 | 全栈工程师之路-www.orlion.ga
查看>>
pyqt5学习3
查看>>
Chapter 9. 线程
查看>>
微信小程序获取复选框全选,反选选中的值
查看>>
vue-awesome-swiper 的 使用
查看>>
好看又实用的英文字体
查看>>
图片的响应式实现
查看>>
Linux学习笔记(二)-Shell教程
查看>>