华为开发者空间
守护线程
守护线程
守护线程(Daemon)Java有两种Thread:“守护线程Daemon”与“用户线程User”。任何线程都可以是“守护线程Daemon”或“用户线程User”。他们在几乎每个方面都是相同的,唯一的区别是用来判断虚拟机何时离开:用户线程:Java虚拟机在它所有非守护线程已经离开后自动离开。守护线程:守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对
守护线程(Daemon)
Java有两种Thread:“
守护线程Daemon”与“
用户线程User”。
任何线程都可以是“ 守护线程Daemon ”或“ 用户线程User ”。他们在几乎每个方面都是相同的,
唯一的区别是用来判断虚拟机何时离开:
用户线程: Java虚拟机在它所有非守护线程已经离开后自动离开。
守护线程 : 守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。
上面是网上的说法。我觉得它的阐述有些地方不妥。我觉得应该是这样的:
唯一的区别是JVM虚拟机根据是否有用户线程来判断的是否该进程该结束
用户线程: 只要有任何用户线程在运行,该进程就不该结束,否则就应该结束。
守护线程: 守护线程则是用来服务用户线程的。如果程序所在的进程没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去,该线程也就会结束,同时程序所在进程也结束。
setDaemon(boolean on)方法可以方便的设置线程的 Daemon模式, true为 Daemon模式, false为 User模式。
setDaemon(boolean on)方法必须在线程启动之前调用,当线程正在运行时调用会产生异常。
isDaemon方法将测试该线程是否为守护线程。值得一提的是, 当你在一个守护线程中产生了其他线程,
那么这些新产生的线程不用设置Daemon属性, 默认是守护线程 ,当然也可以setDaemon设置为用户线程。
当在用户线程中创建线程时, 它默认是用户线程,也可以setDaemon设置为守护线程
例:我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,
程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,
Java虚拟机会自动离开。
示例1
:
import java.io.IOException;
/**
* 守护线程在没有用户线程可服务时自动离开
*/
public class TestMain4 extends Thread {
public TestMain4() {
}
/**
* 线程的run方法,它将和其他线程同时运行
*/
public void run () {
for (int i = 1; i <= 100; i++){
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(i);
}
}
public static void main (String [] args){//这里是个主线程
TestMain4 test = new TestMain4();
test.setDaemon(true);
test.start();
System.out.println("isDaemon = " + test.isDaemon());
try {
System.in.read() ; // 接受输入,使程序在此停顿,一旦接收到用户输入,main线程结束,守护线程自动结束
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
注意: main(String [] args) 这里是个主线程调用的,它是个用户线程。
实例2
:
public class Test {
/**
* @param args
*/
public static void main (String[] args) {
Thread t=new Thread(new MyThread());
t.setDaemon(true);
t.start();
Thread t2=new Thread(new MyThread());
t2.start();
}
}
class MyThread implements Runnable
{
long id=0;
static long count=0;
MyThread ()
{
id=count;
count++;
}
public void run()
{
while (true)
{
try
{
System.out.println("run"+id);
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
注意1
:如果没有t2用户线程进程,t线程在main线程退出后,就没线程可服务了,t线程会结束,
程序所在进程也同时结束了。
任何线程都可以是“ 守护线程Daemon ”或“ 用户线程User ”。他们在几乎每个方面都是相同的,
唯一的区别是用来判断虚拟机何时离开:
用户线程: Java虚拟机在它所有非守护线程已经离开后自动离开。
守护线程 : 守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。
上面是网上的说法。我觉得它的阐述有些地方不妥。我觉得应该是这样的:
用户线程: 只要有任何用户线程在运行,该进程就不该结束,否则就应该结束。
守护线程: 守护线程则是用来服务用户线程的。如果程序所在的进程没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去,该线程也就会结束,同时程序所在进程也结束。
setDaemon(boolean on)方法可以方便的设置线程的 Daemon模式, true为 Daemon模式, false为 User模式。
setDaemon(boolean on)方法必须在线程启动之前调用,当线程正在运行时调用会产生异常。
isDaemon方法将测试该线程是否为守护线程。值得一提的是, 当你在一个守护线程中产生了其他线程,
那么这些新产生的线程不用设置Daemon属性,
当在用户线程中创建线程时, 它默认是用户线程,也可以setDaemon设置为守护线程
例:我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,
程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,
Java虚拟机会自动离开。
import java.io.IOException;
/**
* 守护线程在没有用户线程可服务时自动离开
*/
public class TestMain4 extends Thread {
public TestMain4() {
}
/**
* 线程的run方法,它将和其他线程同时运行
*/
public void run () {
for (int i = 1; i <= 100; i++){
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(i);
}
}
public static void main (String [] args){//这里是个主线程
TestMain4 test = new TestMain4();
test.setDaemon(true);
test.start();
System.out.println("isDaemon = " + test.isDaemon());
try {
System.in.read() ; // 接受输入,使程序在此停顿,一旦接收到用户输入,main线程结束,守护线程自动结束
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
注意: main(String [] args) 这里是个主线程调用的,它是个用户线程。
public class Test {
/**
* @param args
*/
public static void main (String[] args) {
Thread t=new Thread(new MyThread());
t.setDaemon(true);
t.start();
Thread t2=new Thread(new MyThread());
t2.start();
}
}
class MyThread implements Runnable
{
long id=0;
static long count=0;
MyThread ()
{
id=count;
count++;
}
public void run()
{
while (true)
{
try
{
System.out.println("run"+id);
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
程序所在进程也同时结束了。
- 1129
- 0
- 0
- 0
扫一扫分享内容
- 分享
回到
顶部
顶部
所有评论(0)