`

守护线程概念及实例

阅读更多

    守护线程在没有用户线程可服务时自动离开,在Java中比较特殊的线程是被称为守护(Daemon)线程的低级别线程。这个线程具有最低的优先级,用于为系统中的其它对象和线程提供服务。

    将一个用户线程设置为守护线程的方式是在线程对象创建之前调用线程对象的setDaemon方法。典型的守护线程例子是JVM中的系统资源自动回收线程,我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。

    守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”。那Java的守护线程是什么样子的呢。当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则JVM不会退出。

Java有两种Thread:“守护线程Daemon”与“用户线程User”。
我们之前看到的例子都是用户,守护线程是一种“在后台提供通用性支持”的线程,它并不属于程序本体。
从字面上我们很容易将守护线程理解成是由虚拟机(virtual machine)在内部创建的,而用户线程则是自己所创建的。事实并不是这样,任何线程都可以是“守护线程Daemon”或“用户线程User”。他们在几乎每个方面都是相同的,唯一的区别是判断虚拟机何时离开:
用户线程:Java虚拟机在它所有非守护线程已经离开后自动离开。
守护线程:守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。
setDaemon(boolean on)方法可以方便的设置线程的Daemon模式,true为Daemon模式,false为User模式。setDaemon(boolean on)方法必须在线程启动之前调用,当线程正在运行时调用会产生异常。isDaemon方法将测试该线程是否为守护线程。值得一提的是,当你在一个守护线程中产生了其他线程,那么这些新产生的线程不用设置Daemon属性,都将是守护线程,用户线程同样。
实例:
package com.bijian.thread;

import java.io.IOException;

public class DaemonThread extends Thread {
	
	public DaemonThread() {
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(i);
		}
	}

	public static void main(String args[]) {
		DaemonThread daemonThread = new DaemonThread();
		daemonThread.setDaemon(true);
		daemonThread.start();
		System.out.println("isDaemon=" + daemonThread.isDaemon());
		
		//阻塞main方法所在的线程
		try {
			System.in.read();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
         运行结果:
isDaemon=true
0
1
2
3
4
5
6
7
8
9
        如果将阻塞main方法所在的线程的代码去掉,那么结果将不会有数字打印出来。如下所示:
package com.bijian.thread;

public class DaemonThread extends Thread {
	
	public DaemonThread() {
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(i);
		}
	}

	public static void main(String args[]) {
		DaemonThread daemonThread = new DaemonThread();
		daemonThread.setDaemon(true);
		daemonThread.start();
		System.out.println("isDaemon=" + daemonThread.isDaemon());
	}
}
         运行结果:
isDaemon=true
        当然,如果把 thread.setDaemon(true);删除,也能打印出数字,如下所示:
package com.bijian.thread;

public class DaemonThread extends Thread {
	
	public DaemonThread() {
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(i);
		}
	}

	public static void main(String args[]) {
		DaemonThread daemonThread = new DaemonThread();
		//daemonThread.setDaemon(true);
		daemonThread.start();
		System.out.println("isDaemon=" + daemonThread.isDaemon());
	}
}
         运行结果:
isDaemon=false
0
1
2
3
4
5
6
7
8
9
         当然,main方法所在的类不是一个继承Thread类时,只要不设置用户线程为守护线程,也会正常运行的。如下所示:
package com.bijian.thread;

public class DaemonThread {
	
	public DaemonThread() {
	}

	public static void main(String args[]) {

		ThreadAB threadAB = new ThreadAB();
		threadAB.start();
		ThreadAC threadAC = new ThreadAC();
		threadAC.start();
	}
}

class ThreadAB extends Thread {
	
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("ThreadAB:" + i);
		}
	}
}

class ThreadAC extends Thread {
	
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("ThreadAC:" + i);
		}
	}
}
         运行结果:
ThreadAC:0
ThreadAC:1
ThreadAB:0
ThreadAC:2
ThreadAC:3
ThreadAB:1
ThreadAC:4
ThreadAC:5
ThreadAB:2
ThreadAC:6
ThreadAC:7
ThreadAB:3
ThreadAC:8
ThreadAC:9
ThreadAB:4
ThreadAB:5
ThreadAB:6
ThreadAB:7
ThreadAB:8
ThreadAB:9
         在此实例中,如果将ThreadAB设为守护线程,即加上threadAB.setDaemon(true);语句,则结果如下(ThreadAB线程因ThreadAC线程的结束而提前结束):
ThreadAC:0
ThreadAB:0
ThreadAC:1
ThreadAC:2
ThreadAB:1
ThreadAC:3
ThreadAC:4
ThreadAB:2
ThreadAC:5
ThreadAC:6
ThreadAB:3
ThreadAC:7
ThreadAC:8
ThreadAB:4
ThreadAC:9

 

分享到:
评论

相关推荐

    java daemon 守护线程实例

    java daemon 程序,有助于理解守护线程的概念和使用

    Python多线程Threading、子线程与守护线程实例详解

    主要介绍了Python多线程Threading、子线程与守护线程,结合实例形式详细分析了Python多线程Threading、子线程与守护线程相关概念、原理、用法与操作注意事项,需要的朋友可以参考下

    linux programming instances网络编程教程 附源代码

    全书由13章组成,内容涉及到Lindx系统编程基础、TCP/UDP协议、套接字编程概念及I/O模型、高级编程中需要用到的进程问通信同步、多路复用、多线程编程和一些高级套接字控制方法、IPv6介绍以及网络安全等。...

    java8源码-concurrency:java并发总结

    守护线程 1.7 Java内存模型 1.8 可重入 1.9 偏向锁、轻量级锁、重量级锁 1.10 锁的公平性 1.11 线程组 2 多线程基本实现 2.1 多线程实现 Interface Runnable Callable Future ExecutorService Class Thread ...

    嵌入式Linux C编程入门(第2版) PPT

    第10章 arm linux进程线程开发实例 288 10.1 arm linux进程线程管理 289 10.1.1 进程描述符及任务结构 289 10.1.2 进程的调度 291 10.1.3 linux中的线程 293 10.1.4 linux中进程间通信 293 10.2 ...

    Java SE实践教程 源代码 下载

    6.1.8 守护线程 117 6.2 同步与锁 118 6.2.1 synchronized和同步 118 6.2.2 锁对象 120 6.2.3 Condition对象 121 6.2.4 再谈synchronized 122 6.3 协调任务 124 6.3.1 线程池和Executor 124 6.3.2 Callable...

    javaSE代码实例

    16.3.4 守护线程 357 16.4 线程的同步 359 16.4.1 同步方法简介 359 16.4.2 简单使用同步方法 360 16.4.3 线程同步调度的方法 362 16.4.4 “生产者-消费者”案例的框架 362 16.4.5 “生产者-消费者”...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    6.1.8 守护线程 117 6.2 同步与锁 118 6.2.1 synchronized和同步 118 6.2.2 锁对象 120 6.2.3 Condition对象 121 6.2.4 再谈synchronized 122 6.3 协调任务 124 6.3.1 线程池和Executor 124 6.3.2 Callable...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    6.1.8 守护线程 117 6.2 同步与锁 118 6.2.1 synchronized和同步 118 6.2.2 锁对象 120 6.2.3 Condition对象 121 6.2.4 再谈synchronized 122 6.3 协调任务 124 6.3.1 线程池和Executor 124 6.3.2 Callable...

    【python内功修炼002】:并发编程之多进程实例

    文章目录1、multiprocessing模块1.1 multiprocessing模块介绍1.2 multiprocessing常用组件及功能2、Process类常用属性和方法2.1 Process语法2.2 Process类常用属性和方法3、Process类的使用实例3.1 创建并开启子进程...

    UNIX环境高级编程(英文第三版)

    书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在此基础上介绍了众多应用...

    Java并发编程实战

    7.4.2 守护线程136 7.4.3 终结器136 第8章 线程池的使用138 8.1 在任务与执行策略之间的隐性耦合138 8.1.1 线程饥饿死锁139 8.1.2 运行时间较长的任务140 8.2 设置线程池的大小140 8.3 配置...

    UNIX环境高级编程-中文第三版

    书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容外,还介绍了众多应用实例,...

    UNIX环境高级编程(中文第三版)_扫描版.pdf

    书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在此基础上介绍了众多应用...

    Linux C 一站式学习

    1. 线程的概念 2. 线程控制 2.1. 创建线程 2.2. 终止线程 3. 线程间同步 3.1. mutex 3.2. Condition Variable 3.3. Semaphore 3.4. 其它线程间同步机制 4. 编程练习 36. TCP/IP协议基础 1. TCP/IP协议栈与数据包封装...

    Python多进程multiprocessing用法实例分析

    主要介绍了Python多进程multiprocessing用法,结合实例形式分析了Python多线程的概念以及进程的创建、守护进程、终止、退出进程、进程间消息传递等相关操作技巧,需要的朋友可以参考下

    unix环境高级编程第三版

    书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在此基础上介绍了多个应用...

    UNIX环境高级编程 中文第3版

    书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在此基础上介绍了众多应用...

    UNIX环境高级编程(第三版)

    书中除了介绍UNIX文件和目录、标准I/O库、系统数据文件和信息、进程环境、进程控制、进程关系、信号、线程、线程控制、守护进程、各种I/O、进程间通信、网络IPC、伪终端等方面的内容,还在此基础上介绍了众多应用...

    嵌入式Linux 开发ARM课件第一讲

    驱动开发实例:蜂鸣器驱动、按键驱动开发、串口驱动、触摸屏驱动、网络驱动开发、USB驱动、液晶屏驱动等。 ARMlinux移植过程。 引导程序Uboot移植。 最小系统启动开发过程。 嵌入式文件系统移植:ramdisk、JFFS2、...

Global site tag (gtag.js) - Google Analytics