java concurrency: daemon线程
daemon线程的概念
在学习操作系统概念的时候,我们就曾听说过daemon的概念。daemon本身指的是在后台运行的进程或者线程,一般用来提供某些不需要与用户直接交互的服务,有点像我们见到的一些系统服务。在java线程中,一般可以分为两类,一类是普通的线程,就是那些我们通过常用的Thread类或者Runnable接口实现并启动的类。还有一类是daemon线程。这种线程也通过和创建普通线程同样的方式来创建,不过需要通过setDaemon方法设置为daemon线程。
daemon线程有几个典型的特征:
1. daemon线程是运行于后台的,不和用户直接交互。
2. 相对普通的线程来说,daeomn线程可以说是普通线程的下属,它的优先级要低一些。
3. daemon线程具有一定程度的继承性,这个继承性不是指类的继承,而是指当一个daemon线程创建一个新线程的话,这个新创建的线程就默认为daemon线程了。
4. 和普通线程的退出机制不同,在jvm即将关闭的时候,普通线程需要执行一系列的记录或者退出方法,比如需要执行finalize方法的则需要执行这部分,有finally块的代码也必须执行。而daemon线程退出的时候,jvm直接将它丢弃并退出,里面就算有finally块定义的代码也不会被执行。
一个daemon线程的示例
创建或者使用daemon线程一般包括一下3个步骤:
1. 如果线程本身就是daemon线程了,那么通过常规线程创建手段创建出来的就已经是daemon线程。
2. 如果通过普通线程创建创建出来的话,需要在启动线程前调用setDaemon()方法。切记,一定要在调用start()方法前。
3.我们可以通过调用isDaemon()方法来判断一个线程是否为daeomn.
下面是示例代码:
- class MyDaemon implements Runnable
- {
- Thread thrd;
- MyDaemon()
- {
- // Create the thread
- thrd = new Thread(this);
- // Set to daemon
- thrd.setDaemon(true);
- // Start the thread
- thrd.start();
- }
- public void run()
- {
- try
- {
- for(;;)
- {
- System.out.print(".");
- Thread.sleep(1000);
- }
- }
- catch(InterruptedException exc)
- {
- System.out.println("MyDaemon interrupted.");
- }
- }
- }
- class DaemonDemo
- {
- public static void main(String[] args)
- {
- MyDaemon dt = new MyDaemon();
- if(dt.thrd.isDaemon())
- System.out.println("dt is a daemon thread.");
- System.out.println("Sleeping in main thread.");
- try
- {
- Thread.sleep(10000);
- }
- catch(InterruptedException exc)
- {
- System.out.println("Main thread interrupted.");
- }
- System.out.println("\nMain thread ending.");
- }
- }
在上面的代码中,我们实现Runnable接口定义一个MyDaemon类,在构造函数中调用setDaemon()设置该线程为daemon.在main方法中启动MyDaemon线程之后,main方法结束时daemon线程也自动结束了。上述代码的执行结果如下:
- dt is a daemon thread.
- Sleeping in main thread.
- ..........
- Main thread ending.
一个比较有意思的事情就是,如果我们将前面代码里setDaemon()方法的这一行注释了,也就是说将该线程设置为普通的用户线程,再执行上面的代码时,我们会发现,程序不会终止,会一直执行下去,虽然主线程已经结束了。其输出的结果会像如下所示:
- Sleeping in main thread.
- ..........
- Main thread ending.
- .......................
设置daemon线程的意义
从前面的理解来看,daemon线程有点像一个我们画的草图,随时可以丢弃。它一般是用于在jvm关闭的时候,我们需要启动一些线程做一些辅助性的工作,但是我们又不希望这种工作妨碍到jvm正常关闭。和其他正常的线程来说,或许我们应该称之为不碍事的线程更合适。
daemon线程的一些应用
daemon线程在java中有很多地方用到,一个典型的就是垃圾回收的GC线程。另外如果我们需要用线程做一些比如时间提醒,标记等事情,采用daemon线程也是一个比较合适的选择。
又一个daemon的示例
根据前面的理解,我们再尝试一个更复杂的daemon应用。假定我们在一个应用中需要定义一些时间通知,比如说设置在某个指定的时候弹出一个会议通知的提醒。这是一个比较常见的场景,可以用daemon线程来实现。
具体的代码实现如下:
- import java.util.*;
- class Reminder implements Runnable
- {
- Calendar reminderTime;
- String message;
- Reminder(String msg, int delay)
- {
- message = msg;
- // Get the current time and date.
- reminderTime = Calendar.getInstance();
- // Add the delay to the time and date.
- reminderTime.add(Calendar.SECOND, delay);
- System.out.printf("Reminder set for %tD %1$tr\n", reminderTime);
- // Create the reminder thread.
- Thread dThrd = new Thread(this);
- // Set to daemon
- dThrd.setDaemon(true);
- // Start execution.
- dThrd.start();
- }
- // Run the reminder.
- public void run()
- {
- try
- {
- for(;;)
- {
- // Get the current time and date.
- Calendar curTime = Calendar.getInstance();
- // See if it's time for the reminder.
- if(curTime.compareTo(reminderTime) >= 0)
- {
- System.out.println("\n" + message + "\n");
- break;
- }
- Thread.sleep(1000);
- }
- }
- catch(InterruptedException exc)
- {
- System.out.println("Reminder interrupted.");
- }
- }
- }
- class ReminderDemo
- {
- public static void main(String[] args)
- {
- // Get a reminder 2 seconds from now.
- Reminder mt = new Reminder("Call Harry", 2);
- // Keep the main thread alive for 20 seconds.
- for(int i = 0; i < 20; i++)
- {
- try
- {
- Thread.sleep(1000);
- }
- catch(InterruptedException exc)
- {
- System.out.println("Main thread interrupted.");
- }
- System.out.print(".");
- }
- System.out.println("\nMain thread ending.");
- }
- }
我们设置了一个daemon线程,在一个无限循环里比较当前时间和指定的时间,在达到指定的时间时则显示一个提醒消息。上述代码的输出如下:
- Reminder set for 10/21/12 01:57:10 PM
- ..
- Call Harry
- ..................
- Main thread ending.
总结
悄悄的,daemon线程走了,正如daemon线程悄悄的来;挥一挥手,带不走jvm的一片云彩:)
java concurrency: daemon线程的更多相关文章
- 【转】关于Java的Daemon线程的理解
原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.html 关于Java的Daemon线程的理解 网上对Java的Dae ...
- 深入浅出 Java Concurrency (35): 线程池 part 8 线程池的实现及原理 (3)[转]
线程池任务执行结果 这一节来探讨下线程池中任务执行的结果以及如何阻塞线程.取消任务等等. 1 package info.imxylz.study.concurrency.future;2 3 publ ...
- 深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]
线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes t ...
- 深入浅出 Java Concurrency (33): 线程池 part 6 线程池的实现及原理 (1)[转]
线程池数据结构与线程构造方法 由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构.图1描述了这种数据结构. 图1 Thre ...
- 深入浅出 Java Concurrency (30): 线程池 part 3 Executor 生命周期[转]
我们知道线程是有多种执行状态的,同样管理线程的线程池也有多种状态.JVM会在所有线程(非后台daemon线程)全部终止后才退出,为了节省资源和有效释放资源关闭一个线程池就显得很重要.有时候无法正确的关 ...
- 深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]
从这一节开始正式进入线程池的部分.其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充.完善. 其实线程池是并发包里面很重要的一部分,在实际情况 ...
- 深入浅出 Java Concurrency (36): 线程池 part 9 并发操作异常体系[转]
并发包引入的工具类很多方法都会抛出一定的异常,这些异常描述了任务在线程池中执行时发生的例外情况,而通常这些例外需要应用程序进行捕捉和处理. 例如在Future接口中有如下一个API: java.uti ...
- 深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程 ...
- Java Concurrency - 取消线程执行器中的线程
When you work with an executor, you don't have to manage threads. You only implement the Runnable or ...
随机推荐
- 【Howie玩docker】-命令行只显示-bash-4.1#
灵雀云上面用docker建了个centOS的实例,首个免费,正好当云主机来玩. 但是,打开有个问题,命令行不显示当前用户和路径. 只显示: -bash-4.1# 简单,配置文件不全而已. 下面对其重新 ...
- java附件上传下载磁盘版
ACTION public class UploadAction extends BaseAction { private static final long serialVersionUID = 1 ...
- java 如何得到ISO 8601 时间格式
http://blog.csdn.net/brightleo/article/details/7457004 public class DateUtil { public static String ...
- opengl模板缓冲区
相信大家有些人对opengl的模板缓冲区不是很理解,包括我最开始也是,opengl的模板缓冲区其实就是采用过滤的技术来控制那些颜色可以绘制,那些不能进行绘制.这里的过滤技术也就是我们的一个控制方法,主 ...
- [置顶] 【cocos2d-x入门实战】微信飞机大战之二:别急,先处理好CCScene和CCLayer的关系
转载请表明地址:http://blog.csdn.net/jackystudio/article/details/11713197 在整个游戏开始之前,我们先看一下HelloWorld示例中CCSce ...
- .Net之一般处理程序
1.一般处理程序是什么? 答:一般处理程序是以.ashx结尾的文件,默认命名为Handler1.ashx. 用在Web项目中,也就是我们常说的网站项目. 2.新建一个一般处理程序 1.1 新建一个空网 ...
- 简单天气应用开发——API接口
寒假回家无事,想到自学iOS开发已有一段时间,还没做过真正自己的应用,就起了做一个天气预报App的念头. 想到就做.天气预报第一步自然是找到好用的API接口来获取天气信息.在百度上搜索了一圈,找到的都 ...
- jquery回调函数callback的使用
回调函数必须是全局函数或者静态函数,不可定义为某个特定的类的成员函数 callback函数在当前动画100%完成之后执行 $("p").hide(1000); alert(&quo ...
- w2wp.exe 已附加有调试器,但没有将该调试器配置为调试此未经处理的异常
一.问题描述 昨天系统联调,用到了VS2010 附件进程,把w2wp.exe 进程添加到vs2010 的调试进程中,这样其他系统访问我们系统,就可以捕获断点进行调试 但是,今天F5 调试的时候,发现直 ...
- php基础知识(每天分享一些以前的笔记希望能帮助自学的朋友)
php基础(第一天) php标签 1. 要知道php是一种嵌入html文档的脚本语言:php语法格式是:<?php 想要写的内容 ?>红色体就是php的标签,注意这些标签都要在英式输入法 ...