zoukankan      html  css  js  c++  java
  • 线程管理:守护线程的创建和运行

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt204

    线程管理:守护线程的创建和运行

    守护线程的创建和运行
    Java有一种特别的线程叫做守护线程。这种线程的优先级非常低,通常在程序里没有其他线程运行时才会执行它。当守护线程是程序里唯一在运行的线程时,JVM会结束守护线程并终止程序。

    根据这些特点,守护线程通常用于在同一程序里给普通线程(也叫使用者线程)提供服务。它们通常无限循环的等待服务请求或执行线程任务。它们不能做重要的任务,因为我们不知道什么时候会被分配到CPU时间片,并且只要没有其他线程在运行,它们可能随时被终止。JAVA中最典型的这种类型代表就是垃圾回收器。

    在这个指南中, 我们将学习如何创建一个守护线程,开发一个用2个线程的例子;我们的使用线程会写事件到queue, 守护线程会清除queue里10秒前创建的事件。

    准备

    指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。

    怎么做呢…

    按照这些步骤来实现下面的例子:

    1.   创建 Event 类. 这个类只是用来储存我们程序里的工作的事件信息。声明2个属性,一个是java. util.Date 类型的 date 和另一个是String 类型的event 。并生成它们的读值和写值方法。

    2.   创建 WriterTask 类并实现Runnable接口。

    1
    public class WriterTask implements Runnable {
    3.   声明queue,储存事件并实现类的构造函数,初始化queue。

    1
    private Deque<Event> deque;
    2
    public WriterTask (Deque<Event> deque){
    3
    this.deque=deque;
    4
    }
    4.   实现这个任务的 run() 方法 。 此方法有100个循环。在每个循环中我们会创建 一个Event对象,并保存到 queue里, 然后休眠1秒。

    01
    @Override
    02
    public void run() {
    03
    for (int i=1; i<100; i++) {
    04
       Event event=new Event();
    05
       event.setDate(new Date());
    06
       event.setEvent(String.format("The thread %s has generated an   event",Thread.currentThread().getId()));
    07
       deque.addFirst(event);
    08
       try {
    09
          TimeUnit.SECONDS.sleep(1);
    10
       } catch (InterruptedException e) {
    11
          e.printStackTrace();
    12
       }
    13
    }
    14
    }
    5.   创建 CleanerTask 类并一定扩展Thread类。

    1
    public class CleanerTask extends Thread {
    6.   声明 queue,储存事件并实现类的构造函数,初始化queue,在这个构造函数,用setDaemon() 方法让此线程成为守护线程。

    1
    private Deque<Event> deque;
    2
    public CleanerTask(Deque<Event> deque) {
    3
    this.deque = deque;
    4
    setDaemon(true);
    5
    }
    7.   实现run()方法。它是无限循环来获取当前日期并调用 clean() 方法.

    1
    @Override
    2
    public void run() {
    3
    while (true) {
    4
       Date date = new Date();
    5
       clean(date);
    6
    }
    7
    }
    8.   实现 clean() 方法. 它获取最后的事件,如果它在10秒前被创建,就删除它并查看下一个事件。如果一个事件被删除,它会写一个事件信息和queue的新的大小,为了让你看到变化过程。

    01
    private void clean(Date date) {
    02
      long difference;
    03
      boolean delete;
    04
      if (deque.size()==0) {
    05
        return;
    06
      }
    07
      delete=false;
    08
      do {
    09
        Event e = deque.getLast();
    10
        difference = date.getTime() - e.getDate().getTime();
    11
        if (difference > 10000) {
    12
         System.out.printf("Cleaner: %s ",e.getEvent()); deque.removeLast();
    13
         delete=true;
    14
        }
    15
      } while (difference > 10000);
    16
      if (delete){
    17
       System.out.printf("Cleaner: Size of the queue: %d ",deque. size());
    18
      }
    19
    }
    9.   现在实现主类。 创建一个类名为 Main 和 main() 方法。

    1
    public class Main {
    2
    public static void main(String[] args) {
    10. 创建使用 Deque 类的queue 来保存事件。

    1
    Deque<Event> deque=new ArrayDeque<Event>();
    11. 创建 和开始3个 WriterTask 线程和一个 CleanerTask.

    1
    WriterTask writer=new WriterTask(deque);
    2
    for (int i=0; i<3; i++){
    3
    Thread thread=new Thread(writer);
    4
    thread.start();
    5
    }
    6
    CleanerTask cleaner=new CleanerTask(deque);
    7
    cleaner.start();
    12. 运行程序查看结果。

    它是怎么工作的…

    如果分析这个程序的输出,你可以发现queue可以一直增加直到它有30个事件,然后它的大小会在27-30之间直到运行结束。

    程序开始时有3个 WriterTask 线程。每个线程写一个事件然后休眠1秒。10秒之后,我们有30个事件在queue里。在这10秒内,当3个 WriterTask 线程休眠时, CleanerTasks已经开始运行,但是它没有删除任何事件,因为所有事件都才生成不到10秒。在剩下的运行里,CleanerTask 每秒删除3个事件, 然而3个 WriterTask 线程会另写3个,所以queue的大小在27-30之间。

    你可以修改 WriterTask 线程的休眠时间。如果你使用一个较小的值,你会发现CleanerTask 被分配到 CPU 时间片会更少,由于 CleanerTask 没有删除任何事件,所以queue大小会一直增加。

    更多…

    只能在start() 方法之前可以调用 setDaemon() 方法。一旦线程运行了,就不能修改守护状态。

    可以使用 isDaemon() 方法来检查线程是否是守护线程(方法返回 true) 或者是使用者线程 (方法返回 false)。

  • 相关阅读:
    Photoshop
    你会为了钱出售自己的个人资料吗?
    [ElasticSearch] 空间搜索 (一)
    hdu1584 A strange lift (电梯最短路径问题)
    Android API Guides---OpenGL ES
    Qt 推断一个IP地址是否有效
    bzoj1670【Usaco2006 Oct】Building the Moat 护城河的挖掘
    集成学习1-Boosting
    微信开发模式之自己定义菜单实现
    人件札记:开放式的办公室环境
  • 原文地址:https://www.cnblogs.com/grefr/p/6094941.html
Copyright © 2011-2022 走看看