posts - 23,comments - 12,trackbacks - 0

          在Windows編程中可以調(diào)用SetTimer在指定窗口安裝定時(shí)器(Timer),定時(shí)器可以在指定的時(shí)間間隔周期性回調(diào)用戶(hù)指定的方法,用來(lái)執(zhí)行周期性的任務(wù),如果想取消定時(shí)器,可以調(diào)用KillTimer取消。但是在java標(biāo)準(zhǔn)包里中并沒(méi)有這種類(lèi)。下面介紹的這個(gè)類(lèi)包可以實(shí)現(xiàn)上述功能。

          下面是接口,需要支持定時(shí)器功能的類(lèi)要實(shí)現(xiàn)這個(gè)接口:

          TimerClient.java

          package com.ly.util;

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

           

          下面是定時(shí)器的實(shí)現(xiàn),包括三個(gè)類(lèi):TimerCtl,TimerTask,TimerTasks。其中TimerTask用來(lái)描述定時(shí)器信息。TimerTasks是一個(gè)TimerTask的列表,這樣我們就可以同時(shí)在一個(gè)應(yīng)用中安插多個(gè)定時(shí)器。TimerCtl是定時(shí)器控制類(lèi),是個(gè)線(xiàn)程,不停地檢查T(mén)imerTasks中是否有TimerTask到期,要是有TimerTask到達(dá)指定的時(shí)間,則回調(diào)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;
              }
            }
          }

           

           
          下面是一個(gè)使用例子

          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)
          {
          }

          }
          }

           

          通過(guò)這種方式,可以高效地使用socket通訊,在異步socket版本沒(méi)有發(fā)布以前,不失是一種解決問(wèn)題的方法。:)

          posted on 2005-07-26 09:00 my java 閱讀(5824) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): java

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

            回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 贵港市| 双辽市| 高州市| 英吉沙县| 马公市| 聊城市| 马山县| 和政县| 东阿县| 永安市| 绍兴县| 即墨市| 七台河市| 苏尼特右旗| 昌吉市| 紫云| 桃园县| 琼海市| 慈溪市| 南充市| 新泰市| 苗栗县| 象山县| 海口市| 河西区| 江门市| 临泉县| 平罗县| 九江市| 英德市| 楚雄市| 淳安县| 米林县| 东至县| 莆田市| 徐州市| 三台县| 天等县| 西峡县| 上犹县| 象山县|