基于Java线程实现后台定时监控

转载:http://littlefermat.blog.163.com/blog/static/59771167200928115047810/

熟悉编写JavaScript的人,都习惯在页面写入setTimeOut来实现web页面的定时监控或事务处理。但是如何在Java服务端来实现这样一个监控机制呢?一般大家都会想到线程。但是一直以来,都没有亲身动手实践过。趁着工作间隙,自己也搬出一段代码来,与大家一起分享线程编程的神奇魔力。

首先创建一个基本抽象类SchedThread,代码内容如下:

Java代码
  1. package com.test;   
  2.   
  3. /**  
  4.  * 基于Java线程实现后台定时监控 

     Created: Mar 26, 2008 10:08:43 

     

  5.  * 

    http://tailsherry.javaeye.com

     
  6.  * 

     

  7.  *   
  8.  * @author TailSherry  
  9.  */  
  10. public abstract class SchedThread   
  11. {   
  12.     protected static final long NEVER = Long.MAX_VALUE;   
  13.   
  14.     // 定义一个线程锁,保证当前只有一个工作在操作中   
  15.     private final Object lock = new Object();   
  16.   
  17.     // 定义一个Thread变量   
  18.     private Thread thread;   
  19.   
  20.     // 控制线程循环的开关   
  21.     private boolean active = true;   
  22.   
  23.     // 定义一个毫秒级的时间变量,指示何时执行下一个操作   
  24.     private long nextTime;   
  25.   
  26.     /**  
  27.      * 定义个一个抽象的方法用来获取下一个执行操作的时间,可使用NEVER  
  28.      */  
  29.     protected abstract long getNextTime();   
  30.   
  31.     /**  
  32.      * 定义一个抽象的方法,让子类来定义具体的工作过程  
  33.      */  
  34.     protected abstract void executeWork();   
  35.   
  36.     protected String getName()   
  37.     {   
  38.         return getClass().getName();   
  39.     }   
  40.   
  41.     /**  
  42.      * 启动线程  
  43.      */  
  44.     public void start()   
  45.     {   
  46.         thread = new Thread(new Runnable()   
  47.         {   
  48.             public void run()   
  49.             {   
  50.                 runInternal();   
  51.             }   
  52.         }, getName());   
  53.         thread.start();   
  54.     }   
  55.   
  56.     /**  
  57.      * 强迫停止线程,跳出for循环  
  58.      */  
  59.     public void stop() throws InterruptedException   
  60.     {   
  61.         synchronized (lock)   
  62.         {   
  63.             active = false;   
  64.             lock.notify();   
  65.         }   
  66.         thread.join();   
  67.     }   
  68.   
  69.     /**  
  70.      * 此方法可以在任何时候激活当前线程,让线程进入工作执行环节  
  71.      */  
  72.     public void workAdded(long time)   
  73.     {   
  74.         synchronized (lock)   
  75.         {   
  76.             if (time < nextTime)   
  77.             {   
  78.                 // 立刻激活线程工作继续运行   
  79.                 lock.notify();   
  80.             }   
  81.         }   
  82.     }   
  83.   
  84.     /**  
  85.      * 线程监测控制逻辑部分  
  86.      */  
  87.     private void runInternal()   
  88.     {   
  89.         // 无限循环   
  90.         for (;;)   
  91.         {   
  92.             // 该过程忽略了所有的Exception,以保证线程不会因此而中断   
  93.             try  
  94.             {   
  95.                 synchronized (lock)   
  96.                 {   
  97.                     nextTime = getNextTime();   
  98.                     // 获得时间区间,即要等待的时间段   
  99.                     long interval = nextTime - System.currentTimeMillis();   
  100.                     if (interval > 0)   
  101.                     {   
  102.                         try  
  103.                         {   
  104.                             lock.wait(interval);   
  105.                         }   
  106.                         catch (InterruptedException e)   
  107.                         {   
  108.                             // 忽略此Exception   
  109.                         }   
  110.                     }   
  111.                     // 如果active为false,强制中断   
  112.                     if (!active)   
  113.                     {   
  114.                         break;   
  115.                     }   
  116.                 }   
  117.                 // 执行具体的工作   
  118.                 executeWork();   
  119.             }   
  120.             catch (Throwable t)   
  121.             {   
  122.                 try  
  123.                 {   
  124.                     Thread.sleep(10000);   
  125.                 }   
  126.                 catch (InterruptedException ie)   
  127.                 {   
  128.                     // 忽略此Exception   
  129.                 }   
  130.             }   
  131.         }   
  132.     }   
  133. }  
package com.test;

/**
 * 基于Java线程实现后台定时监控 

Created: Mar 26, 2008 10:08:43

*

http://tailsherry.javaeye.com

*

* * @author TailSherry */ public abstract class SchedThread { protected static final long NEVER = Long.MAX_VALUE; // 定义一个线程锁,保证当前只有一个工作在操作中 private final Object lock = new Object(); // 定义一个Thread变量 private Thread thread; // 控制线程循环的开关 private boolean active = true; // 定义一个毫秒级的时间变量,指示何时执行下一个操作 private long nextTime; /** * 定义个一个抽象的方法用来获取下一个执行操作的时间,可使用NEVER */ protected abstract long getNextTime(); /** * 定义一个抽象的方法,让子类来定义具体的工作过程 */ protected abstract void executeWork(); protected String getName() { return getClass().getName(); } /** * 启动线程 */ public void start() { thread = new Thread(new Runnable() { public void run() { runInternal(); } }, getName()); thread.start(); } /** * 强迫停止线程,跳出for循环 */ public void stop() throws InterruptedException { synchronized (lock) { active = false; lock.notify(); } thread.join(); } /** * 此方法可以在任何时候激活当前线程,让线程进入工作执行环节 */ public void workAdded(long time) { synchronized (lock) { if (time < nextTime) { // 立刻激活线程工作继续运行 lock.notify(); } } } /** * 线程监测控制逻辑部分 */ private void runInternal() { // 无限循环 for (;;) { // 该过程忽略了所有的Exception,以保证线程不会因此而中断 try { synchronized (lock) { nextTime = getNextTime(); // 获得时间区间,即要等待的时间段 long interval = nextTime - System.currentTimeMillis(); if (interval > 0) { try { lock.wait(interval); } catch (InterruptedException e) { // 忽略此Exception } } // 如果active为false,强制中断 if (!active) { break; } } // 执行具体的工作 executeWork(); } catch (Throwable t) { try { Thread.sleep(10000); } catch (InterruptedException ie) { // 忽略此Exception } } } } }

 

以上这个类非常关键,基本上已经实现了所有的控制逻辑,如此再扩展出一个实现类出来,比如这里我写了一个模拟实现类MyDataGenerator,大家可以参考一下:

Java代码
  1. package com.test;   
  2.   
  3. public class MyDataGenerator extends SchedThread {   
  4.     protected void executeWork() {   
  5.         System.out.println("Execute work ...");   
  6.     }   
  7.   
  8.     protected long getNextTime() {   
  9.         return System.currentTimeMillis() + 2000L;   
  10.     }   
  11.   
  12.     public static void main(String argv[]) {   
  13.         MyDataGenerator generator = new MyDataGenerator();   
  14.         generator.start();   
  15.     }   
  16. }  
package com.test;

public class MyDataGenerator extends SchedThread {
    protected void executeWork() {
        System.out.println("Execute work ...");
    }

    protected long getNextTime() {
        return System.currentTimeMillis() + 2000L;
    }

    public static void main(String argv[]) {
        MyDataGenerator generator = new MyDataGenerator();
        generator.start();
    }
}

  

当然这里没有使用workAdded和stop等功能,可以留给大家扩展。

你可能感兴趣的:(___,J2SE)