文档章节

Java并发编程初级篇(六):守护线程

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/11/23 15:03
字数 809
阅读 40
收藏 0

Java中的提供的守护线程优先级很低。也就是说,当同一个应用中中没有其他线程运行的时候,守护线程才运行,当其他线程都已经终止后,守护线程成为了唯一的运行线程时,那么守护线程就会终止,JVM应用结束。

因为守护线程的特性,通常情况下守护线程是用来为普通线程提供服务的。它在结构设计上是无限循环的,并且不能够承担重要工作,因为我们不知道守护线程什么时候能够获取CPU时间,守护线程也不能够独立存在。在Java中,守护线程最典型的一个例子就是垃圾收集器(GC)。

在Java API中提供了Thread.setDaemon(true)方法把一个线程设置成守护线程。

下面我们来实现一个守护线程的例子,在这里例子中我们模拟一个生产者不断地向Deque中生产Event对象,然后模拟一个守护进程,它的作用就是检查Deque来保证Deque中的Event生产时间都是10秒内的。

首先我们定义一个Event对象,它有两个属性,一个是生产时间,一个是名称。

public 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;
    }
}

下面我们定义一个生产者线程,用来不断地向Deque中生产Event对象,并记录生产时间。

public class ProducerTask implements Runnable {
    private Deque<Event> deque;

    public ProducerTask(Deque<Event> deque) {
        this.deque = deque;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            Event event = new Event();
            event.setDate(new Date());
            event.setEvent(Thread.currentThread().getName() + " Event:" + i);
            deque.addFirst(event);

            System.out.printf("%s: Produce one event %s.\n", Thread.currentThread().getName(), event.getEvent());

            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

定义守护线程,保证Deque中生产的Event对象都是10秒内的。

public class GuardTask implements Runnable {
    private Deque<Event> deque;

    public GuardTask(Deque<Event> deque) {
        this.deque = deque;
    }

    @Override
    public void run() {
        while (true) {
            Event event = deque.getLast();

            Date now = new Date();

            if (now.getTime() - event.getDate().getTime() > 10000) {
                deque.removeLast();

                System.out.printf("%s: Clean Deque %s. Deque size is %d.\n",
                        Thread.currentThread().getName(),
                        event.getEvent(),
                        deque.size());
            }
        }
    }
}

定义主方法类,启动三个生产者线程,并注册一个守护线程。

public class Main {
    public static void main(String[] args) {
        Deque<Event> deque = new ArrayDeque<Event>();

        Thread producer1 = new Thread(new ProducerTask(deque), "Producer-1");
        Thread producer2 = new Thread(new ProducerTask(deque), "Producer-2");
        Thread producer3 = new Thread(new ProducerTask(deque), "Producer-3");

        producer1.start();
        producer2.start();
        producer3.start();

        //创建守护线程
        Thread guard = new Thread(new GuardTask(deque), "Guard");
        guard.setDaemon(true);

        guard.start();
    }
}

查看日志,我们会发现因为守护线程的存在,保证了Deque中的Event数量稳定在了27-30个,最后当所有线程都结束后,守护线程也就结束了。

Producer-3: Produce one event Producer-3 Event:98.
Producer-2: Produce one event Producer-2 Event:98.
Producer-1: Produce one event Producer-1 Event:98.
Guard: Clean Deque Producer-3 Event:89. Deque size is 24.
Guard: Clean Deque Producer-2 Event:89. Deque size is 23.
Guard: Clean Deque Producer-1 Event:89. Deque size is 22.
Producer-3: Produce one event Producer-3 Event:99.
Producer-2: Produce one event Producer-2 Event:99.
Producer-1: Produce one event Producer-1 Event:99.
Guard: Clean Deque Producer-3 Event:90. Deque size is 24.
Guard: Clean Deque Producer-1 Event:90. Deque size is 23.

 

© 著作权归作者所有

共有 人打赏支持
阿拉德大陆的魔法师
粉丝 23
博文 91
码字总数 83019
作品 0
西城
程序员
JAVA多线程和并发基础面试问答

原文链接 译文连接 作者:Pankaj 译者:郑旭东 校对:方腾飞 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢...

雷神雨石
2014/07/19
0
2
JAVA多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:...

LCZ777
2014/05/26
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

清风傲剑
2014/12/06
0
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

hanzhankang
2014/01/20
0
0
java并发编程(六): 取消与关闭

取消与关闭: 如何正确,安全地取消或关闭任务。 任务取消: 若外部代码能在某个操作正常完成之前将其置入“完成”状态,则还操作是可取消的。 取消操作的原因: 1. 用户请求取消。 2. 有时间...

ihaolin
2014/03/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

面向对象类之间的关系

面向对象类之间的关系:is-a、has-a、use-a is-a关系也叫继承或泛化,比如大雁和鸟类之间的关系就是继承。 has-a关系称为关联关系,例如企鹅在气候寒冷的地方生活,“企鹅”和“气候”就是关...

gackey
48分钟前
1
0
读书(附电子书)|小狗钱钱之白色的拉布拉多

关注公众号,在公众号中回复“小狗钱钱”可免费获得电子书。 一、背景 之前写了一篇文章 《小狗钱钱》 理财小白应该读的一本书,那时候我才看那本书,现在看了一大半了,发现这本书确实不错,...

tiankonguse
今天
1
0
Permissions 0777 for ‘***’ are too open

异常显示: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ......

李玉长
今天
3
0
区块链10年了,还未落地,它失败了吗?

导读 几乎每个人,甚至是对通证持怀疑态度的人,都对区块链的技术有积极的看法,因为它有可能改变世界。然而,区块链技术问世已经10年了,我们仍然没有真正的用上区块链技术。 几乎每个人,甚...

问题终结者
今天
2
0
20180921 su与sudo命令、限制root用户通过ssh远程登录

su 命令 用户切换。 su # 切换到root用户su username # 切换到username用户# su 后面加-时,会初始化当前用户的各种环境su - username # 指定用户执行某些命令 su - -c "touch /tm...

野雪球
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部