Java有一种特殊线程叫守护(后台)线程。

1.这类线程拥有非常低的优先级且通常只是在没有其他线程运行的情况下执行。

2.其通常作为无线循环服务去执行某项任务。

3.不能让他们去执行重要任务因为你不知道他们什么时候获得CPU时间或者何时运行结束。

4.一个很典型的案例就是Java的垃圾收集器。

本例中,我们将学习如何去差U你感觉一个守护线程。

为此,我们会开发2个线程;一个用来往队列中写入事件,另一个也就是守护线程用来清理10s之前写入的事件。

  1.  
  1. Event.java
  1. package com.dylan.thread.ch1.c07;
  2. import java.util.Date;
  3. /**
  4. * 事件类
  5. * @author xusucheng
  6. * @create 2018-04-14
  7. **/
  8. public class Event {
  9. private Date date;
  10. private String event;
  11. public Date getDate() {
  12. return date;
  13. }
  14. public void setDate(Date date) {
  15. this.date = date;
  16. }
  17. public String getEvent() {
  18. return event;
  19. }
  20. public void setEvent(String event) {
  21. this.event = event;
  22. }
  23. }
  1. WriterTask.java
  1. package com.dylan.thread.ch1.c07;
  2. import com.dylan.thread.ch1.c07.Event;
  3. import java.util.Date;
  4. import java.util.Deque;
  5. import java.util.concurrent.TimeUnit;
  6. /**
  7. * 写事件类
  8. * @author xusucheng
  9. * @create 2018-04-14
  10. **/
  11. public class WriterTask implements Runnable {
  12. /**
  13. * Data structure to stores the events
  14. */
  15. Deque<Event> deque;
  16. /**
  17. * Constructor of the class
  18. * @param deque data structure that stores the event
  19. */
  20. public WriterTask (Deque<Event> deque){
  21. this.deque=deque;
  22. }
  23. /**
  24. * Main class of the Runnable
  25. */
  26. @Override
  27. public void run() {
  28. // Writes 100 events
  29. for (int i=1; i<100; i++) {
  30. // Creates and initializes the Event objects
  31. Event event=new Event();
  32. event.setDate(new Date());
  33. event.setEvent(String.format("The thread %s has generated an event",Thread.currentThread().getId()));
  34. // Add to the data structure
  35. deque.addFirst(event);
  36. try {
  37. // Sleeps during one second
  38. TimeUnit.SECONDS.sleep(1);
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. }
  1. CleanerTask.java
  1. package com.dylan.thread.ch1.c07;
  2. import java.util.ArrayDeque;
  3. import java.util.Date;
  4. import java.util.Deque;
  5. /**
  6. * 清理事件类
  7. *
  8. * @author xusucheng
  9. * @create 2018-04-14
  10. **/
  11. public class CleanerTask extends Thread {
  12. /**
  13. * Data structure that stores events
  14. */
  15. private Deque<Event> deque;
  16. /**
  17. * Constructor of the class
  18. * @param deque data structure that stores events
  19. */
  20. public CleanerTask(Deque<Event> deque) {
  21. this.deque = deque;
  22. // Establish that this is a Daemon Thread
  23. setDaemon(true);
  24. }
  25. /**
  26. * Main method of the class
  27. */
  28. @Override
  29. public void run() {
  30. while (true) {
  31. Date date = new Date();
  32. clean(date);
  33. }
  34. }
  35. /**
  36. * Method that review the Events data structure and delete
  37. * the events older than ten seconds
  38. * @param date
  39. */
  40. private void clean(Date date) {
  41. long difference;
  42. boolean delete;
  43. if (deque.size()==0) {
  44. return;
  45. }
  46. delete=false;
  47. do {
  48. Event e = deque.getLast();
  49. difference = date.getTime() - e.getDate().getTime();
  50. if (difference > 10000) {
  51. System.out.printf("Cleaner: %s\n",e.getEvent());
  52. deque.removeLast();
  53. delete=true;
  54. }
  55. } while (difference > 10000);
  56. if (delete){
  57. System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());
  58. }
  59. }
  60. }


  1. Main.java
  1. package com.dylan.thread.ch1.c07;
  2. import java.util.ArrayDeque;
  3. import java.util.Deque;
  4. /**
  5. * @author xusucheng
  6. * @create 2018-04-27
  7. **/
  8. public class Main {
  9. /**
  10. * Main method of the example. Creates three WriterTasks and a CleanerTask
  11. * @param args
  12. */
  13. public static void main(String[] args) {
  14. // Creates the Event data structure
  15. Deque<Event> deque=new ArrayDeque<Event>();
  16. // Creates the three WriterTask and starts them
  17. WriterTask writer=new WriterTask(deque);
  18. for (int i=0; i<3; i++){
  19. Thread thread=new Thread(writer);
  20. thread.start();
  21. }
  22. // Creates a cleaner task and starts them
  23. CleanerTask cleaner=new CleanerTask(deque);
  24. cleaner.start();
  25. }
  26. }

调试输出:

Cleaner: The thread 14 has generated an event
Cleaner: Size of the queue: 30
Cleaner: The thread 13 has generated an event
Cleaner: The thread 15 has generated an event
Cleaner: The thread 15 has generated an event
Cleaner: The thread 14 has generated an event
Cleaner: The thread 13 has generated an event

...

Java并发编程实例--7.守护(Damon)线程的更多相关文章

  1. java并发编程笔记(七)——线程池

    java并发编程笔记(七)--线程池 new Thread弊端 每次new Thread新建对象,性能差 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或者OOM 缺 ...

  2. java并发编程笔记(五)——线程安全策略

    java并发编程笔记(五)--线程安全策略 不可变得对象 不可变对象需要满足的条件 对象创建以后其状态就不能修改 对象所有的域都是final类型 对象是正确创建的(在对象创建期间,this引用没有逸出 ...

  3. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  4. 【Java并发编程】之二:线程中断

    [Java并发编程]之二:线程中断 使用interrupt()中断线程 ​ 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一 ...

  5. java并发编程笔记(三)——线程安全性

    java并发编程笔记(三)--线程安全性 线程安全性: ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现 ...

  6. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  7. 《Java并发编程实战》学习笔记 线程安全、共享对象和组合对象

    Java Concurrency in Practice,一本完美的Java并发参考手册. 查看豆瓣读书 推荐:InfoQ迷你书<Java并发编程的艺术> 第一章 介绍 线程的优势:充分利 ...

  8. Java并发编程(四):线程安全性

    一.定义 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的. 二.线程安 ...

  9. 读书笔记-----Java并发编程实战(一)线程安全性

    线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet @ThreadSafe public class StatelessFactorizer ...

  10. java并发编程(十五)----(线程池)java线程池简介

    好的软件设计不建议手动创建和销毁线程.线程的创建和销毁是非常耗 CPU 和内存的,因为这需要 JVM 和操作系统的参与.64位 JVM 默认线程栈是大小1 MB.这就是为什么说在请求频繁时为每个小的请 ...

随机推荐

  1. Mygin实现简单的路由

    本文是Mygin第二篇 目的: 实现路由映射 提供了用户注册静态路由方法(GET.POST方法) 基于上一篇 Mygin 实现简单Http 且参照Gin 我使用了map数组实现简单路由的映射关系 不同 ...

  2. [转帖]理解 Linux backlog/somaxconn 内核参数

    引言 在研究IOTDB的时候,启动服务的时候会有个报警. WARN: the value of net.core.somaxconn (=4096) is too small, please set ...

  3. Numa以及其他内存参数等对Oracle的影响

    Numa以及其他内存参数等对Oracle的影响 背景知识: Numa的理解 Numa 分一致性内存访问结构 主要是对应UMA 一致性内存访问而言的. 在最初一个服务器只有一个CPU的场景下, 都是UM ...

  4. [转帖]paramiko简介

    https://www.cnblogs.com/qiujichu/p/12048763.html 一.什么是paramiko 要想明白什么是paramiko,要先明白ssh协议. 二.什么是ssh协议 ...

  5. [转帖]CPU的制造和概念

    https://plantegg.github.io/2021/06/01/CPU%E7%9A%84%E5%88%B6%E9%80%A0%E5%92%8C%E6%A6%82%E5%BF%B5/ 为了让 ...

  6. 通过写脚本的方式自动获取JVM内的进程堆栈信息等内容

    公司转java之后 经常会遇到java进程占用CPU特别多的情况. 每次连上机器进行处理都比较慢了. 索性自己写一个脚本, 把想要查询的信息直接汇总进去. 这样的话 就简单很多了. 脚本也很简单主要如 ...

  7. Nginx 按天拆分日志

    https://blog.csdn.net/linpxing1/article/details/104059857 ### 关键位置 start if ($time_iso8601 ~ '(\d{4} ...

  8. 2024年最新的Python操控微信教程

    自从微信禁止网页版登陆之后,itchat 库实现的功能也就都不能用了,那现在 Python 还能操作微信吗?答案是:可以! 在Github上有一个项目叫<WeChatPYAPI>可以使用 ...

  9. echarts使用transform缩放后导致图标模糊

    echarts使用transform缩放后导致图标模糊 --的解决办法 当使用了transform: scale(x,y)缩放后致使echarts图表模糊.怎么解决这个问题呢? 第一种解决办法:将ca ...

  10. linux虚拟机固定ip

    1.查看宿主机IP信息 在windows宿主机上,键盘输入win+r,输出cmd,打开终端命令行: 输入ipconfig /all,查看宿主机IP信息: 2.修改Linux虚拟机的配置文件 Linux ...