守护线程和Shutdown Hooks_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 守护线程和Shutdown Hooks

守护线程和Shutdown Hooks

 2014/9/4 18:25:35  shensuqiao  程序员俱乐部  我要评论(0)
  • 摘要:线程分为两种:守护线程和用户线程(也叫非守护线程)。可以通过Thread的setDaemon(booleanon)方法将其设定为守护线程或用户线程。setDaemon方法必须在线程启动前被调用。不然会产生IllegalThreadStateException异常。并且,守护线程具有传递性,即如果一个线程是守护线程,那么它的子线程也会是守护线程。守护线程是为了服务于用户线程而存在的,所以当Java的执行环境结束(调用System.exit方法停止JVM时,或者所有非守护线程都结束时
  • 标签:线程

class="MsoNormal">线程分为两种:守护线程和用户线程(也叫非守护线程)。

?

可以通过ThreadsetDaemon(boolean on)方法将其设定为守护线程或用户线程。

setDaemon方法必须在线程启动前被调用。不然会产生IllegalThreadStateException异常

并且,守护线程具有传递性,即如果一个线程是守护线程,那么它的子线程也会是守护线程。

?

守护线程是为了服务于用户线程而存在的,所以当Java的执行环境结束(调用System.exit方法停止JVM,或者所有非守护线程都结束时)守护线程也会退出。

?

有一点注意了,在application中要慎用用户线程,因为当JVM中存在alive的用户线程时,有可能会出现服务停止超时的情况。(当然,有些服务停止时会去调用System.exit方法,就不会有容器停止超时的情况出现)。

比如,GlassFish3.1.2JavaEE6Cluster停止的时候就不会去调用System.exit方法。

?

但是,守护线程也不是使用与所有的情况下的。比如:读写操作或者逻辑计算

我们看下面的一个例子

public class DaemonThread extends Thread {
	public void run() {
		for (int i = 0; i < 999; i++) {
			System.out.println("This is Daemon Thread:" + i);
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class UserThread extends Thread {
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println("This is User Thread:" + i);
			try {
				Thread.sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

public class HookTest {
	public static void main(String[] args) {
		Thread t1 = new DaemonThread();
		Thread t2 = new UserThread();

		t1.setDaemon(true);

		t1.start();
		t2.start();
	}
}

?

?此时,console中输出如下:

This is Daemon Thread:0
This is User Thread:0
This is User Thread:1
This is Daemon Thread:1
This is User Thread:2
This is Daemon Thread:2
This is User Thread:3
This is Daemon Thread:3
This is User Thread:4
This is Daemon Thread:4
This is Daemon Thread:5

?

可以看到:程序只保证了User Thread执行,Daemon Thread并没有执行完成就退出了。

?

那是不是这个问题不能解决呢?当然不是,使用RuntimeaddShutdownHook(Thread hook)方法就可以!

addShutdownHook方法会在JVM停止前被调用,也就是说,JVM会等addShutdownHook中的Thread执行结束后才关闭。这样,就可以等用户的操作都结束后,才退出JVM

?

上面的那个例子,Main函数就可以改写为以下的样子:?

public static void main(String[] args){
	Runtime.getRuntime().addShutdownHook(
		new Thread(){
			public void run(){
				System.out.println("This is Shutdown Hook!!!");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	);
	
	Thread t1 = new DaemonThread();
	Thread t2 = new UserThread();
	t1.setDaemon(true);//设置为守护程序
	t1.start();
	t2.start();
}

?此时,consloe中输出如下:

This is Daemon Thread:0
This is User Thread:0
This is User Thread:1
This is Daemon Thread:1
This is User Thread:2
This is Daemon Thread:2
This is User Thread:3
This is Daemon Thread:3
This is User Thread:4
This is Daemon Thread:4
This is Daemon Thread:5
This is Shutdown Hook!!!
This is Daemon Thread:6
……
This is Daemon Thread:996
This is Daemon Thread:997
This is Daemon Thread:998

?可以看到:User Thread执行结束后,JVM并不是马上就退出,而是调用了addShutdownHooksleep10000ms后再退出。

?

上一篇: HBase的集群安装 下一篇: Process类
发表评论
用户名: 匿名