posts - 23,comments - 12,trackbacks - 0

          在Windows編程中可以調用SetTimer在指定窗口安裝定時器(Timer),定時器可以在指定的時間間隔周期性回調用戶指定的方法,用來執行周期性的任務,如果想取消定時器,可以調用KillTimer取消。但是在java標準包里中并沒有這種類。下面介紹的這個類包可以實現上述功能。

          下面是接口,需要支持定時器功能的類要實現這個接口:

          TimerClient.java

          package com.ly.util;

          /**
           * TimerClient Interface
           *
           * @version 1.0, 8 October 1995
           *
           */
          public interface TimerClient
          {
            void timerEvent(int id);
          }

           

          下面是定時器的實現,包括三個類:TimerCtl,TimerTask,TimerTasks。其中TimerTask用來描述定時器信息。TimerTasks是一個TimerTask的列表,這樣我們就可以同時在一個應用中安插多個定時器。TimerCtl是定時器控制類,是個線程,不停地檢查TimerTasks中是否有TimerTask到期,要是有TimerTask到達指定的時間,則回調TimerTask指定的TimerClient的timerEvent接口。

          TimerCtl.java

          package com.ly.util;

          import java.util.Vector;
          import java.util.Enumeration;
          //import com.borland.jb.util.Diagnostic;

          /**
           * Timer Component
           *
           * Note:
           *  - The successful operation of this timer requires clients to execute simple, short
           *    code snippets when called back by the engine.  Otherwise the queue's delivery
           *    mechanism will be held up
           *
           * Further work:
           *  - When Thread.Interrupt is implemented we can switch from the busy wait model to
           *    the calculated wait model.  Without the interrupt the thread waits for the
           *    calculated interval before waking up.  This is a problem if another shorter
           *    request arrives.  For now we'll assume the minimum resolution of the timer is
           *    100ms.
           *
           * @version 1.0, 2 October 1995
           *
           */
          public class TimerCtl
          {
            static TimerTasks timerTasks;

            public TimerCtl() {
            }

            /*
            * Start a timer running
            */
            public static void startTimer(TimerClient client, int eventId, long delay, boolean repeat) {
              // create the timer if necessary
              if (timerTasks == null) {
                timerTasks = new TimerTasks();
                timerTasks.start();
              }

              //Diagnostic.out.println("TIMER: startTimer"+eventId);

              // add the new task to the queue
              timerTasks.add(client, eventId, delay, repeat);
            }

            /*
            * Stop a timer
            */
            public static void stopTimer(TimerClient client, int eventId) {
              //Diagnostic.out.println("TIMER: stopTimer"+eventId);
              if(timerTasks != null)
                  timerTasks.end(client, eventId);
            }
          }

          class TimerTasks extends Thread
          {
            Vector tasks = new Vector();
            boolean suspended = false;
            boolean sleeping = false;

            /**
             * Thread task runner
             */
            public void run() {
              // Loop forever
              while (true) {
                long sleepTime = 0;

                // Ensure that the tasks class is protected
                synchronized (tasks) {
                  //Diagnostic.out.println("TIMER: Tick");

                  // Scan the job list for any jobs which may fire.
                  // Mark one-shot jobs for deletion
                  // Calculate the maximum time we can sleep for
                  sleepTime = scan();

                  // Delete DeletePending jobs.  DeletePending jobs result from one-shots which have
                  // been sent, and repeat jobs which have been cancelled.  Jobs may have been
                  // cancelled during the Scan process.
                  purge();
                }

                // Suspend timer if necessary
                if (tasks.size() == 0) {
                  //Diagnostic.out.println("TIMER: Suspend");
                  try {
                    synchronized(this) {
                      suspended = true;
                      wait();
                    }
                  }
                  catch (InterruptedException e) {
                  }
                }
                else {
                  //Diagnostic.out.println("TIMER: Suggested Sleeping for "+sleepTime);
                  if (sleepTime >= 0) {
                    try {
                      sleeping = true;
                      sleep(sleepTime);
                      sleeping = false;
                    }
                    catch (InterruptedException i) {
                      //Diagnostic.out.println("TIMER: Caught me napping");
                    }
                  }
                }
              }
            }

            /**
             * Add a new task
             */
            public void add(TimerClient client, int eventId, long delay, boolean repeat) {
              TimerTask t = new TimerTask(client, eventId, delay, repeat);

              synchronized (tasks) {
                tasks.addElement((Object)t);
              }

              // Want instant response - wake the thread if it's napping
              // unfortunately the interrupt() method is not working
          //    if (sleeping)
          //      interrupt();

              if (suspended) {
                synchronized(this) {
                  notify();
                  //Diagnostic.out.println("TIMER: Resume");
                  suspended = false;
                }
              }
            }

            /**
             * Find the job and mark it for deletion
             */
            public void end(TimerClient client, int eventId) {
              synchronized (tasks) {
                for (int i = 0; i < tasks.size(); i++) {
                  TimerTask t = (TimerTask)tasks.elementAt(i);

                  //if (!t.deletePending && t.client == client && t.eventId == eventId)
                  if (t.deletePending == false && t.client == client && t.eventId == eventId) {
                    // JPBS - if we don't reset 'repeat', deletePending will be set again
                    t.repeat = false;
                    t.deletePending = true;
                    break;
                  }
                }
              }
            }

            /**
             * Clear out all the dead wood
             */
            void purge() {
              for (int i = 0; i < tasks.size(); i++) {
                TimerTask t = (TimerTask)tasks.elementAt(i);

                if (t.deletePending) {
                  //Diagnostic.out.println("TIMER: purged");

                  tasks.removeElementAt(i);
                  i--;
                }
              }
            }

            long scan() {
              // The value added to the current time determines the MAX time until
              // the next scan
              // This is 100 now since thread.interrupt() is not implemented
              long nextTime = System.currentTimeMillis() + 100;

              for (int i = 0; i < tasks.size(); i++) {
                TimerTask t = (TimerTask)tasks.elementAt(i);

                // if not already deletePending, test (and possibly send the event)
                // as a result, the job may be flagged for deletion.
                // May also be a non-repeating job and so require self deletion
                if (!t.deletePending)
                  t.test();

                // if the task didn't get deleted - see what it contributes to the time
                if (!t.deletePending)
                  nextTime = Math.min(nextTime, t.timeNext);

                //Diagnostic.out.println("TIMER: Scanning "+t.eventId+" "+(t.deletePending == true ? "DEL" : ""));
              }

              return nextTime - System.currentTimeMillis();
            }
          }

          class TimerTask
          {
            TimerClient client;
            int         eventId;

            long        timePrev;
            long        timeDelay;
            long        timeNext;

            boolean repeat;
            boolean deletePending;

            public TimerTask(TimerClient client, int eventId, long timeDelay, boolean repeat) {
              this.client = client;
              this.eventId = eventId;
              this.timeDelay = timeDelay;
              this.repeat = repeat;

              // schedule the next click - now + delay
              timeNext = System.currentTimeMillis() + timeDelay;
              deletePending = false;

              //Diagnostic.out.println("TIMER: Adding New Task");
            }

            public void test() {
              if (System.currentTimeMillis() >= timeNext) {
                //Diagnostic.out.println("TIMER: fire");

                // Fire the event
                client.timerEvent(eventId);

                // Update the next time
                timeNext = System.currentTimeMillis() + timeDelay;

                deletePending = !repeat;
              }
            }
          }

           

           
          下面是一個使用例子

          TimerTest.java

          package com.ly.util;

          import java.io.*;
          import java.util.*;
          import com.ly.util.*;

          /**
          * Title:
          * Description:
          * Copyright: Copyright (c) 2001
          * Company: http://dozb.blogchina.com
          * @author dozb
          * @version 1.0
          */
          public class TimerTest implements TimerClient{
          public TimerTest()
          {
          starttime();
          }
          public void timerEvent(int id)
          {
          System.out.println("timerEvent...");
          }
          public void starttime()
          {
          TimerCtl.startTimer(this,1,5*1000,true);
          }
          public void stoptime()
          {
          TimerCtl.stopTimer(this,1);
          }

          public static void main(String[] args)
          {
          new TimerTest();
          try
          {
          Thread.sleep(200000);
          }catch(Exception e)
          {
          }

          }
          }

           

          通過這種方式,可以高效地使用socket通訊,在異步socket版本沒有發布以前,不失是一種解決問題的方法。:)

          posted on 2005-07-26 09:00 my java 閱讀(5823) 評論(1)  編輯  收藏 所屬分類: java

          FeedBack:
          # re: java中定時器timer類的實現和源代碼
          2006-07-27 11:49 | supercai
          在TimerTasks的run()中
          try {
          sleeping = true;
          sleep(sleepTime);
          sleeping = false;
          }
          catch (InterruptedException i) {
          應該是
          try {
          sleeping = true;
          sleep(sleepTime);
          sleepTime=scan();
          sleeping = false;
          }
          catch (InterruptedException i) {
          才能正確執行

            回復  更多評論
            
          主站蜘蛛池模板: 莒南县| 衡阳市| 怀化市| 夹江县| 铁岭市| 莱西市| 疏附县| 安多县| 阜新| 绿春县| 巴南区| 那曲县| 昌都县| 三门峡市| 渑池县| 东辽县| 临潭县| 博乐市| 深圳市| 新巴尔虎左旗| 双峰县| 铁力市| 子洲县| 淅川县| 北流市| 金湖县| 宾川县| 塘沽区| 九台市| 淅川县| 酒泉市| 新乐市| 乌审旗| 西充县| 新津县| 武鸣县| 新邵县| 江都市| 曲阳县| 屯门区| 乌什县|