文档章节

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

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/11/23 15:03
字数 809
阅读 50
收藏 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.

 

© 著作权归作者所有

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

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

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

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

hanzhankang
2014/01/20
0
0
进一步理解Java中的线程(下)

要想真正的理解Java并发编程,线程是无论如何都必须要彻底理解的一个重要概念。那么,在开始深入介绍之前,我们先来深入的学习一下线程。前面一个章节中已经介绍过线程的一些基本知识,包括线...

HollisChuang's Blog
2018/12/22
0
0
JAVA多线程和并发基础面试问答

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

清风傲剑
2014/12/06
0
0
java并发编程(六): 取消与关闭

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

ihaolin
2014/03/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

携程Apollo统一配置中心的搭建和使用(java)

一.Apollo配置中心介绍 1、What is Apollo 1.1 Apollo简介 Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到...

morpheusWB
39分钟前
1
0
远程获得的有趣的linux命令

使用这些工具从远程了解天气、阅读资料等。 我们即将结束为期 24 天的 Linux 命令行玩具日历。希望你有一直在看,如果没有,请回到开始,从头看过来。你会发现 Linux 终端有很多游戏、消遣和...

Linux就该这么学
54分钟前
6
0
聊聊flink的AsyncWaitOperator

序 本文主要研究一下flink的AsyncWaitOperator AsyncWaitOperator flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/operators/async/AsyncWaitOperator.java ......

go4it
今天
5
0
Java并发编程基础(四)

ThreadGroup 在主线程创建得线程,如果没有给他指定线程组,那么创建的线程,默认和主线程同一个线程组。线程组可以底下可以是线程,也可以实线程组。 构建线程组的方法: private ThreadGr...

chendom
今天
7
0
Scala学习(一)

学习Spark之前需要学习Scala。 参考学习的书籍:快学Scala

柠檬果过
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部