Java里有一种特殊的线程叫做守护(Daemon)线程,这种线程的优先级很低,通常来说,当一个应用程序里面没有其他线程运行的时候,守护线程才运行,当线程是程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个程序。因此,守护线程通常被用来作为同一程序中普通线程的服务提供者,通常是无线循环的,以等待服务请求或者线程任务。

  代码实现

  1:创建Event类,声明两个私有属性

  

  1. package com.packtpub.java7.concurrency.chapter1.recipe7.event;
  2.  
  3. import java.util.Date;
  4.  
  5. /**
  6. * Class that stores event's information
  7. *
  8. */
  9. public class Event {
  10.  
  11. /**
  12. * Date of the event
  13. */
  14. private Date date;
  15.  
  16. /**
  17. * Message of the event
  18. */
  19. private String event;
  20.  
  21. /**
  22. * Reads the Date of the event
  23. * @return the Date of the event
  24. */
  25. public Date getDate() {
  26. return date;
  27. }
  28.  
  29. /**
  30. * Writes the Date of the event
  31. * @param date the date of the event
  32. */
  33. public void setDate(Date date) {
  34. this.date = date;
  35. }
  36.  
  37. /**
  38. * Reads the message of the event
  39. * @return the message of the event
  40. */
  41. public String getEvent() {
  42. return event;
  43. }
  44.  
  45. /**
  46. * Writes the message of the event
  47. * @param event the message of the event
  48. */
  49. public void setEvent(String event) {
  50. this.event = event;
  51. }
  52. }

  2:创建WirterTask类,实现Runnable接口,声明一个存放Event对象的队列,并实现一个带参数的构造器,初始化这个队列,实现线程的run()方法,执行循环100次,每次循环中都会创建一个新的Event对象,并放入队列中,然后休眠1秒钟

  1. package com.packtpub.java7.concurrency.chapter1.recipe7.task;
  2.  
  3. import java.util.Date;
  4. import java.util.Deque;
  5. import java.util.concurrent.TimeUnit;
  6.  
  7. import com.packtpub.java7.concurrency.chapter1.recipe7.event.Event;
  8.  
  9. /**
  10. * Runnable class that generates and event every second
  11. *
  12. */
  13. public class WriterTask implements Runnable {
  14.  
  15. /**
  16. * Data structure to stores the events
  17. */
  18. Deque<Event> deque;
  19.  
  20. /**
  21. * Constructor of the class
  22. * @param deque data structure that stores the event
  23. */
  24. public WriterTask (Deque<Event> deque){
  25. this.deque=deque;
  26. }
  27.  
  28. /**
  29. * Main class of the Runnable
  30. */
  31. @Override
  32. public void run() {
  33.  
  34. // Writes 100 events
  35. for (int i=1; i<100; i++) {
  36. // Creates and initializes the Event objects
  37. Event event=new Event();
  38. event.setDate(new Date());
  39. event.setEvent(String.format("The thread %s has generated an event",Thread.currentThread().getId()));
  40.  
  41. // Add to the data structure
  42. deque.addFirst(event);
  43. try {
  44. // Sleeps during one second
  45. TimeUnit.SECONDS.sleep(1);
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. }
  51. }

  3 创建CleanerTask类,并继承Thread类,声明存放Event对象的队列,也实现一个带参数的构造器,来初始化这个队列,在这个构造器中用setDaemon()方法,把这个线程设为守护线程。实现run()方法,他将无线的重复运行,并在每次运行中,取当前时间,调用clean()方法。实现clean()方法,读取队列的最后一个事件对象,如果这个事件是10s钟之前创建的,将他删除并且检查下一个,如果有时间被删除,clean()将打印出删除事件的信息,

  1. package com.packtpub.java7.concurrency.chapter1.recipe7.task;
  2.  
  3. import java.util.Date;
  4. import java.util.Deque;
  5.  
  6. import com.packtpub.java7.concurrency.chapter1.recipe7.event.Event;
  7.  
  8. /**
  9. * Class that review the Event data structure and delete
  10. * the events older than ten seconds
  11. *
  12. */
  13. public class CleanerTask extends Thread {
  14.  
  15. /**
  16. * Data structure that stores events
  17. */
  18. private Deque<Event> deque;
  19.  
  20. /**
  21. * Constructor of the class
  22. * @param deque data structure that stores events
  23. */
  24. public CleanerTask(Deque<Event> deque) {
  25. this.deque = deque;
  26. // Establish that this is a Daemon Thread
  27. setDaemon(true);
  28. }
  29.  
  30. /**
  31. * Main method of the class
  32. */
  33. @Override
  34. public void run() {
  35. while (true) {
  36. Date date = new Date();
  37. clean(date);
  38. }
  39. }
  40.  
  41. /**
  42. * Method that review the Events data structure and delete
  43. * the events older than ten seconds
  44. * @param date
  45. */
  46. private void clean(Date date) {
  47. long difference;
  48. boolean delete;
  49.  
  50. if (deque.size()==0) {
  51. return;
  52. }
  53.  
  54. delete=false;
  55. do {
  56. Event e = deque.getLast();
  57. difference = date.getTime() - e.getDate().getTime();
  58. if (difference > 10000) {
  59. System.out.printf("Cleaner: %s\n",e.getEvent());
  60. deque.removeLast();
  61. delete=true;
  62. }
  63. } while (difference > 10000);
  64. if (delete){
  65. System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());
  66. }
  67. }
  68. }

  

  4:实现主类

  

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

  打印结果

  1. Cleaner: Size of the queue: 28
  2. Cleaner: The thread 9 has generated an event
  3. Cleaner: Size of the queue: 28
  4. Cleaner: The thread 11 has generated an event
  5. Cleaner: Size of the queue: 29
  6. Cleaner: The thread 10 has generated an event
  7. Cleaner: Size of the queue: 28
  8. Cleaner: The thread 9 has generated an event
  9. Cleaner: Size of the queue: 28
  10. Cleaner: The thread 11 has generated an event
  11. Cleaner: Size of the queue: 29
  12. Cleaner: The thread 10 has generated an event
  13. Cleaner: Size of the queue: 28
  14. Cleaner: The thread 9 has generated an event
  15. Cleaner: Size of the queue: 28
  16. Cleaner: The thread 11 has generated an event
  17. Cleaner: Size of the queue: 29
  18. Cleaner: The thread 10 has generated an event
  19. Cleaner: Size of the queue: 29
  20. Cleaner: The thread 9 has generated an event
  21. Cleaner: Size of the queue: 28

我们会发现,队列中的对象会不断增长至30个,然后程序结束,队列的长度维持在27-30之间,这个程序有3个WriteTask线程,每个线程向队列写入一个事件,然后休眠1秒钟,在第一个10s中,队列中有30个事件,直到3个WriterTask都结束后,CleanTask才开始执行,但是他没有删除任何事件,因为所有的事件都小于10秒钟,在接下来运行中,CleanTask每秒钟删除3个事件,同时WriteTask会写入3个对象,所以队列一直在27-30之间。

  

  

  

Java7并发编程实战(一) 守护线程的创建和运行的更多相关文章

  1. [笔记][Java7并发编程实战手冊]系列文件夹

    推荐学习多线程之前要看的书. [笔记][思维导图]读深入理解JAVA内存模型整理的思维导图文章里面的思维导图或则相应的书籍.去看一遍. 能理解为什么并发编程就会出现故障. Java7并发编程实战手冊 ...

  2. 《Java7并发编程实战手册》读书笔记

    一.线程管理 1.线程的创建和运行 创建线程的2种方式: 继承Thread类,并覆盖run()方法 创建一个实现Runnable接口的类.使用带参数的Thread构造器来创建Thread对象 每个Ja ...

  3. [笔记][Java7并发编程实战手冊]3.8 并发任务间的数据交换Exchanger

    [笔记][Java7并发编程实战手冊]系列文件夹 简单介绍 Exchanger 是一个同步辅助类.用于两个并发线程之间在一个同步点进行数据交换. 同意两个线程在某一个点进行数据交换. 本章exchan ...

  4. [笔记][Java7并发编程实战手冊]3.4 等待多个并发事件的完毕CountDownLatch倒计数闭锁

    [笔记][Java7并发编程实战手冊]系列文件夹 简单介绍 本文学习CountDownLatch 倒计数闭锁. 本人英文不好.靠机器翻译,然后有一段非常形象的描写叙述,让我把它叫为倒计数 用给定的计数 ...

  5. 【JAVA并发第二篇】Java线程的创建与运行,线程状态与常用方法

    1.线程的创建与运行 (1).继承或直接使用Thread类 继承Thread类创建线程: /** * 主类 */ public class ThreadTest { public static voi ...

  6. Java7并发编程实战(一) 线程的管理

    1:线程的创建   1:继承Thread类,并且覆盖run()方法  2:创建一个实现Runnable接口的类.使用带参数的Thread构造器来构造 2:example-->计算打印乘法表 首先 ...

  7. 【Java并发编程】:守护线程与线程阻塞的四种情况

    守护线程 JAVA中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台线程的运 ...

  8. 漫谈并发编程(二):java线程的创建与基本控制

    java线程的创建 定义任务           在java中使用任务这个名词来表示一个线程控制流的代码段,用Runnable接口来标记一个任务,该接口的run方法为线程运行的代码段. public ...

  9. Java7并发编程实战(一) 线程的等待

    试想一个情景,有两个线程同时工作,还有主线程,一个线程负责初始化网络,一个线程负责初始化资源,然后需要两个线程都执行完毕后,才能执行主线程 首先创建一个初始化资源的线程 public class Da ...

随机推荐

  1. 1.10 基础知识——GP3.1 制度化 & GP3.2 收集改进信息

    摘要: GP3.1是要求建立组织级的关于该过程的制度.标准.模版等全套体系,要求覆盖该PA所有的SP和GP.GP3.2 体现的是持续改进,每个过程都应该收集相应的改进信息. 正文: GP3.1 Est ...

  2. ORACLE口令管理

    口令文件介绍 在ORALCE数据库系统中,用户如果要以特权用户身份(SYS/SYSDBA/SYSOPER)登录ORALCE数据库可以有两种身份验证的方法:即使用与操作系统集成的身份验证或使用ORALC ...

  3. Sql Server之旅——第十站 看看DML操作对索引的影响

    我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 ...

  4. Windows7 系统 CMD命令行,点阵字体不能改变大小以及中文乱码的问题

    之前装了oracle 11g后,发现开机速度竟然奇葩的达到了3分钟.经过旁边大神指点,说是因为oracle某个(具体不清楚)服务,在断网的时候会不断的ping网络,导致速度变慢.然后就关服务呗,然后一 ...

  5. RedHat Linux 9.0的安装+入门指南(图文并茂)

    一,准备工作1,购买或下载Redhat9的安装光盘(3张盘)或镜像文件2,在硬盘中至少留2个分区给安装系统用,挂载点所用分区推荐4G以上,交换分区不用太大在250M左右比较适合,文件系统格式不论,反正 ...

  6. ctargs使用

    ctargs为源码的变量/对象.结构体/类.函数/接口.宏等产生索引文件,以便快速定位.目前支持41种语言,这里仅以C/C++为例:ctags可以产生c/c++语言所有类型的索引文件,具体如下: -& ...

  7. hdfs 机架感知和复制因子的设置

    dfs.replication 新更新的复制因子的参数对原来的文件不起作用. 譬如说,原来的复制因子是2,则原来文件上传的时候就只有两个副本. 现在把dfs.replication设置为3,重新启动h ...

  8. Spring AOP 5种通知与java动态代理

    接口,要求为每个方法前后添加日志  @Component("arithmeticCalculator") public class ArithmeticCalculatorImpl ...

  9. Java注解的使用

    概念:java提供了一种原程序中的元素关联任何信息和任何元数据的途径和方法. Java中的常见注解 JDK自带注解: @Override//覆盖父类的方法 @Deprecated//表示方法过时了 @ ...

  10. 关于PHP上传文件和中文名乱码情况

    关于PHP文件上传 在前端HTML页面,表单如下 Upload.html <!doctype html><html lang="en"><head&g ...