zoukankan      html  css  js  c++  java
  • 用户线程 (User Thread)、守护线程 (Daemon Thread)

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

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

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

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

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

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

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

    代码示例:

    import java.util.concurrent.TimeUnit;

     

    /**

     *  守护线程

     */

    public class Daemons {

     

        /**

         * @param args

         * @throws InterruptedException

         */

        public static void main(String[] args) throws InterruptedException {

            Thread d = new Thread(new Daemon());

            d.setDaemon(true); //必须在启动线程前调用

            d.start();

            System.out.println("d.isDaemon() = " + d.isDaemon() + ".");

            TimeUnit.SECONDS.sleep(1);

        }

     

    }

     

    class DaemonSpawn implements Runnable {

     

        public void run() {

            while (true) {

                Thread.yield();

            }

        }

       

    }

     

    class Daemon implements Runnable {

        private Thread[] t = new Thread[10];

     

        public void run() {

            for (int i=0; i<t.length; i++) {

                t[i] = new Thread(new DaemonSpawn());

                t[i].start();

                System.out.println("DaemonSpawn " + i + " started.");

            }

            for (int i=0; i<t.length; i++) {

                System.out.println("t[" + i + "].isDaemon() = " +

                        t[i].isDaemon() + ".");

            }

            while (true) {

                Thread.yield();

            }

        }

       

    }

     

    运行结果:

    d.isDaemon() = true.

    DaemonSpawn 0 started.

    DaemonSpawn 1 started.

    DaemonSpawn 2 started.

    DaemonSpawn 3 started.

    DaemonSpawn 4 started.

    DaemonSpawn 5 started.

    DaemonSpawn 6 started.

    DaemonSpawn 7 started.

    DaemonSpawn 8 started.

    DaemonSpawn 9 started.

    t[0].isDaemon() = true.

    t[1].isDaemon() = true.

    t[2].isDaemon() = true.

    t[3].isDaemon() = true.

    t[4].isDaemon() = true.

    t[5].isDaemon() = true.

    t[6].isDaemon() = true.

    t[7].isDaemon() = true.

    t[8].isDaemon() = true.

    t[9].isDaemon() = true.

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

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

    d.isDaemon() = true.

    DaemonSpawn 0 started.

    DaemonSpawn 1 started.

    DaemonSpawn 2 started.

    DaemonSpawn 3 started.

    DaemonSpawn 4 started.

    DaemonSpawn 5 started.

    DaemonSpawn 6 started.

    DaemonSpawn 7 started.

    DaemonSpawn 8 started.

    DaemonSpawn 9 started.

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

    代码示例:

    import java.util.concurrent.TimeUnit;

     

    /**

     * Finally shoud be always run ?

     */

    public class DaemonsDontRunFinally {

     

        /**

         * @param args

         */

        public static void main(String[] args) {

            Thread t = new Thread(new ADaemon());

            t.setDaemon(true);

            t.start();

        }

     

    }

     

    class ADaemon implements Runnable {

     

        public void run() {

            try {

                System.out.println("start ADaemon...");

                TimeUnit.SECONDS.sleep(1);

            } catch (InterruptedException e) {

                System.out.println("Exiting via InterruptedException");

            } finally {

                System.out.println("This shoud be always run ?");

            }

        }

       

    }

     

    运行结果:

    start ADaemon...

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

    start ADaemon...

    This shoud be always run ?

  • 相关阅读:
    bzoj1415 NOI2005聪聪和可可
    Tyvj1952 Easy
    poj2096 Collecting Bugs
    COGS 1489玩纸牌
    COGS1487 麻球繁衍
    cf 261B.Maxim and Restaurant
    cf 223B.Two Strings
    cf 609E.Minimum spanning tree for each edge
    cf 187B.AlgoRace
    cf 760B.Frodo and pillows
  • 原文地址:https://www.cnblogs.com/aligege/p/7551415.html
Copyright © 2011-2022 走看看