Java并发编程:守护线程

在Java中有两类线程:用户线程 (User Thread)、守护线程 (Daemon Thread)。

所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

用户线程和守护线程两者几乎没有区别,***的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

将线程转换为守护线程可以通过调用Thread对象的setDaemon(true)方法来实现。在使用守护线程时需要注意一下几点:

(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。

(2) 在Daemon线程中产生的新线程也是Daemon的。

(3) 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

代码示例:

 
 
 
  1. import java.util.concurrent.TimeUnit;
  2. /**
  3. * 守护线程
  4. */
  5. public class Daemons {
  6. /**
  7. * @param args
  8. * @throws InterruptedException 
  9. */
  10. public static void main(String[] args) throws InterruptedException {
  11. Thread d = new Thread(new Daemon());
  12. d.setDaemon(true); //必须在启动线程前调用
  13. d.start();
  14. System.out.println("d.isDaemon() = " + d.isDaemon() + ".");
  15. TimeUnit.SECONDS.sleep(1);
  16. }
  17. }
  18. class DaemonSpawn implements Runnable {
  19. public void run() {
  20. while (true) {
  21. Thread.yield();
  22. }
  23. }
  24. }
  25. class Daemon implements Runnable {
  26. private Thread[] t = new Thread[10];
  27. public void run() {
  28. for (int i=0; i
  29. t[i] = new Thread(new DaemonSpawn());
  30. t[i].start();
  31. System.out.println("DaemonSpawn " + i + " started.");
  32. }
  33. for (int i=0; i
  34. System.out.println("t[" + i + "].isDaemon() = " +
  35. t[i].isDaemon() + ".");
  36. }
  37. while (true) {
  38. Thread.yield();
  39. }
  40. }
  41. }

运行结果:

 
 
 
  1. d.isDaemon() = true.
  2. DaemonSpawn 0 started.
  3. DaemonSpawn 1 started.
  4. DaemonSpawn 2 started.
  5. DaemonSpawn 3 started.
  6. DaemonSpawn 4 started.
  7. DaemonSpawn 5 started.
  8. DaemonSpawn 6 started.
  9. DaemonSpawn 7 started.
  10. DaemonSpawn 8 started.
  11. DaemonSpawn 9 started.
  12. t[0].isDaemon() = true.
  13. t[1].isDaemon() = true.
  14. t[2].isDaemon() = true.
  15. t[3].isDaemon() = true.
  16. t[4].isDaemon() = true.
  17. t[5].isDaemon() = true.
  18. t[6].isDaemon() = true.
  19. t[7].isDaemon() = true.
  20. t[8].isDaemon() = true.
  21. t[9].isDaemon() = true.

以上结果说明了守护线程中产生的新线程也是守护线程。

如果将mian函数中的TimeUnit.SECONDS.sleep(1);注释掉,运行结果如下:

 
 
 
  1. d.isDaemon() = true.
  2. DaemonSpawn 0 started.
  3. DaemonSpawn 1 started.
  4. DaemonSpawn 2 started.
  5. DaemonSpawn 3 started.
  6. DaemonSpawn 4 started.
  7. DaemonSpawn 5 started.
  8. DaemonSpawn 6 started.
  9. DaemonSpawn 7 started.
  10. DaemonSpawn 8 started.
  11. DaemonSpawn 9 started.

以上结果说明了如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。下面的例子也说明了这个问题。

代码示例:

 
 
 
  1. import java.util.concurrent.TimeUnit;
  2. /**
  3. * Finally shoud be always run ?
  4. */
  5. public class DaemonsDontRunFinally {
  6. /**
  7. * @param args
  8. */
  9. public static void main(String[] args) {
  10. Thread t = new Thread(new ADaemon());
  11. t.setDaemon(true);
  12. t.start();
  13. }
  14. }
  15. class ADaemon implements Runnable {
  16. public void run() {
  17. try {
  18. System.out.println("start ADaemon...");
  19. TimeUnit.SECONDS.sleep(1);
  20. } catch (InterruptedException e) {
  21. System.out.println("Exiting via InterruptedException");
  22. } finally {
  23. System.out.println("This shoud be always run ?");
  24. }
  25. }
  26. }

运行结果:

start ADaemon...

如果将main函数中的t.setDaemon(true);注释掉,运行结果如下:

start ADaemon...

This shoud be always run ?

分享题目:Java并发编程:守护线程
网页地址:http://www.hantingmc.com/qtweb/news28/452678.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联