熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

Java語言中Timer類的簡潔用法(一)

2013-11-15 11:50:33  來源: JSP教程 

  所有類型的 Java 應用程序一般都需要計劃重復執行的任務企業應用程序需要計劃每日的日志或者晚間批處理過程一個 JSE 或者 JME 日歷應用程序需要根據用戶的約定計劃鬧鈴時間不過標准的調度類 Timer 和 TimerTask 沒有足夠的靈活性無法支持通常需要的計劃任務類型在本文中Java 開發人員 Tom White 向您展示了如何構建一個簡單通用的計劃框架以用於執行任意復雜的計劃任務
  
  我將把 javautilTimer 和 javautilTimerTask 統稱為 Java 計時器框架它們使程序員可以很容易地計劃簡單的任務(注意這些類也可用於 JME 中)在 Java SDK Standard Edition Version 中引入這個框架之前開發人員必須編寫自己的調度程序這需要花費很大精力來處理線程和復雜的 Objectwait() 方法不過Java 計時器框架沒有足夠的能力來滿足許多應用程序的計劃要求甚至一項需要在每天同一時間重復執行的任務也不能直接使用 Timer 來計劃因為在夏令時開始和結束時會出現時間跳躍
  
  本文展示了一個通用的 Timer 和 TimerTask 計劃框架從而允許更靈活的計劃任務這個框架非常簡單 —— 它包括兩個類和一個接口 —— 並且容易掌握如果您習慣於使用 Java 定時器框架那麼您應該可以很快地掌握這個計劃框架
  
  計劃單次任務
  計劃框架建立在 Java 定時器框架類的基礎之上因此在解釋如何使用計劃框架以及如何實現它之前我們將首先看看如何用這些類進行計劃
  
  想像一個煮蛋計時器在數分鐘之後(這時蛋煮好了)它會發出聲音提醒您清單 中的代碼構成了一個簡單的煮蛋計時器的基本結構它用 Java 語言編寫
  
  清單 EggTimer 類
  
  package orgtilingschedulingexamples;
  
  import javautilTimer;
  import javautilTimerTask;
  
  public class EggTimer {
    private final Timer timer = new Timer();
    private final int minutes;
  
    public EggTimer(int minutes) {
      thisminutes = minutes;
    }
  
    public void start() {
      timerschedule(new TimerTask() {
        public void run() {
          playSound();
          timercancel();
        }
        private void playSound() {
          Systemoutprintln(Your egg is ready!);
          // Start a new thread to play a sound
        }
      } minutes * * );
    }
  
    public static void main(String[] args) {
      EggTimer eggTimer = new EggTimer();
      eggTimerstart();
    }
  
  }
  EggTimer 實例擁有一個 Timer 實例用於提供必要的計劃用 start() 方法啟動煮蛋計時器後它就計劃了一個 TimerTask在指定的分鐘數之後執行時間到了Timer 就在後台調用 TimerTask 的 start() 方法這會使它發出聲音在取消計時器後這個應用程序就會中止
  
  計劃重復執行的任務
  通過指定一個固定的執行頻率或者固定的執行時間間隔Timer 可以對重復執行的任務進行計劃不過有許多應用程序要求更復雜的計劃例如每天清晨在同一時間發出叫醒鈴聲的鬧鐘不能簡單地使用固定的計劃頻率 毫秒( 小時)因為在鐘撥快或者撥慢(如果您的時區使用夏令時)的那些天裡叫醒可能過晚或者過早解決方案是使用日歷算法計算每日事件下一次計劃發生的時間而這正是計劃框架所支持的考慮清單 中的 AlarmClock 實現
  
  清單 AlarmClock 類
  
  package orgtilingschedulingexamples;
  
  import javatextSimpleDateFormat;
  
  import javautilDate;
  
  import orgtilingschedulingScheduler;
  import orgtilingschedulingSchedulerTask;
  import orgtilingscheratorsDailyIterator;
  
  public class AlarmClock {
  
    private final Scheduler scheduler = new Scheduler();
    private final SimpleDateFormat dateFormat =
      new SimpleDateFormat(dd MMM yyyy HH:mm:ssSSS);
    private final int hourOfDay minute second;
  
    public AlarmClock(int hourOfDay int minute int second) {
      thishourOfDay = hourOfDay;
      thisminute = minute;
      thissecond = second;
    }
  
    public void start() {
      schedulerschedule(new SchedulerTask() {
        public void run() {
          soundAlarm();
        }
        private void soundAlarm() {
          Systemoutprintln(Wake up! +
            Its + dateFormatformat(new Date()));
          // Start a new thread to sound an alarm
        }
      } new DailyIterator(hourOfDay minute second));
    }
  
    public static void main(String[] args) {
      AlarmClock alarmClock = new AlarmClock( );
      alarmClockstart();
    }
  }
  注意這段代碼與煮蛋計時器應用程序非常相似AlarmClock 實例擁有一個 Scheduler (而不是 Timer)實例用於提供必要的計劃啟動後這個鬧鐘對 SchedulerTask (而不是 TimerTask)進行調度用以發出報警聲這個鬧鐘不是計劃一個任務在固定的延遲時間後執行而是用 DailyIterator 類描述其計劃在這裡它只是計劃任務在每天上午 : 執行下面是一個正常運行情況下的輸出
  
  Wake up! Its Aug ::
  Wake up! Its Aug ::
  Wake up! Its Aug ::
  Wake up! Its Aug ::
  Wake up! Its Aug ::
  
  
  DailyIterator 實現了 ScheduleIterator這是一個將 SchedulerTask 的計劃執行時間指定為一系列 javautilDate 對象的接口然後 next() 方法按時間先後順序迭代 Date 對象返回值 null 會使任務取消(即它再也不會運行)—— 這樣的話試圖再次計劃將會拋出一個異常清單 包含 ScheduleIterator 接口
  
  清單 ScheduleIterator 接口
  
  package orgtilingscheduling;
  
  import javautilDate;
  
  public interface ScheduleIterator {
    public Date next();
  }
  DailyIterator 的 next() 方法返回表示每天同一時間(上午 :)的 Date 對象如清單 所示所以如果對新構建的 next() 類調用 next()那麼將會得到傳遞給構造函數的那個日期當天或者後面一天的 : AM再次調用 next() 會返回後一天的 : AM如此重復為了實現這種行為DailyIterator 使用了 javautilCalendar 實例構造函數會在日歷中加上一天對日歷的這種設置使得第一次調用 next() 會返回正確的 Date注意代碼沒有明確地提到夏令時修正因為 Calendar 實現(在本例中是 GregorianCalendar)負責對此進行處理所以不需要這樣做
  
  清單 DailyIterator 類
  
  package orgtilingscherators;
  
  import orgtilingschedulingScheduleIterator;
  
  import javautilCalendar;
  import javautilDate;
  
  /**
   * A DailyIterator class returns a sequence of dates on subsequent days
   * representing the same time each day
   */
  public class DailyIterator implements ScheduleIterator {
    private final int hourOfDay minute second;
    private final Calendar calendar = CalendargetInstance();
  
    public DailyIterator(int hourOfDay int minute int second) {
      this(hourOfDay minute second new Date());
    }
  
    public DailyIterator(int hourOfDay int minute int second Date date) {
      thishourOfDay = hourOfDay;
      thisminute = minute;
      thissecond = second;
      calendarsetTime(date);
      calendarset(CalendarHOUR_OF_DAY hourOfDay);
      calendarset(CalendarMINUTE minute);
      calendarset(CalendarSECOND second);
      calendarset(CalendarMILLISECOND );
      if (!calendargetTime()before(date)) {
        calendaradd(CalendarDATE );
      }
    }
  
    public Date next() {
      calendaradd(CalendarDATE );
      return calendargetTime();
    }
  
  }
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19734.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.