Java Tutorial/Development/Timer

Материал из Java эксперт
Перейти к: навигация, поиск

Class encapsulating timer functionality

/*
 * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
 * 
 * Project: OpenSubsystems
 * 
 * $Id: MyTimer.java,v 1.5 2007/01/07 06:14:00 bastafidli Exp $
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License. 
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

/**
 * Class encapsulating timer functionality.
 * 
 * @version $Id: MyTimer.java,v 1.5 2007/01/07 06:14:00 bastafidli Exp $
 * @author Miro Halas
 * @code.reviewer Miro Halas
 * @code.reviewed Initial revision
 */
public class MyTimer
{
   // Attributes ///////////////////////////////////////////////////////////////
   
   /**
    * Remeber start time here.
    */
   private long m_lStartTime;
   
   /**
    * Remeber stop time here.
    */
   private long m_lStopTime;
   // Constructors /////////////////////////////////////////////////////////////
   
   /**
    * Default constructor.
    * Starts counting fro the moment it is cosntructed.
    */
   public MyTimer(
   )
   {
      reset();
   }
   // Logic ////////////////////////////////////////////////////////////////////
   
   /**
    * @return long - start time;
    */
   public long getStartTime()
   {
      return m_lStartTime;
   }
   /**
    * @return - stop time;
    */
   public long getStopTime()
   {
      return m_lStopTime;
   }
   /**
    * Reset the counter and start counting from scratch.
    */
   public void reset(
   )
   {
      m_lStartTime = System.currentTimeMillis();
      m_lStopTime = 0;
   }
   /**
    * Stop the timer.
    */
   public void stop(
   )
   {
      m_lStopTime = System.currentTimeMillis();
   }
   /**
    * Get timer duration (the timer doesn"t stop) in milliseconds.
    * 
    * @return long - difference between stop and start time.
    */
   public long getDuration(
   )
   {
      long lStopTime;
      if (m_lStopTime == 0)
      {
         lStopTime = System.currentTimeMillis();
      }
      else
      {
         lStopTime = m_lStopTime;
      }
      return lStopTime - m_lStartTime;
   }
   /**
    * Print the state of the timer without stopping it.
    * @return String - timing information
    */
   public String toString(
   )
   {
      long lTotalMS   = getDuration();
      long lMS        = lTotalMS % 1000;
      long lTotalSecs = lTotalMS / 1000;
      long lSecs      = lTotalSecs % 60;
      long lTotalMins = lTotalSecs / 60;
      long lMinutes   = lTotalMins % 60;
      long lHours     = lTotalMins / 60;
      StringBuffer sbBuffer = new StringBuffer();
      if (lHours > 0)
      {
         sbBuffer.append(lHours);
         sbBuffer.append(":");
         sbBuffer.append(lMinutes);
         sbBuffer.append(":");
         sbBuffer.append(lSecs);
         sbBuffer.append(".");
         sbBuffer.append(lMS);
      }
      else if (lMinutes > 0)
      {
         sbBuffer.append(lMinutes);
         sbBuffer.append(":");
         sbBuffer.append(lSecs);
         sbBuffer.append(".");
         sbBuffer.append(lMS);
      }
      else if (lSecs > 0)
      {
         sbBuffer.append(lSecs);
         sbBuffer.append(".");
         sbBuffer.append(lMS);
         sbBuffer.append(" seconds");
      }
      else
      {
         sbBuffer.append(lMS);
         sbBuffer.append(" ms");
      }
      
      return sbBuffer.toString();
   }
}





Create a scheduled task using timer

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Main extends TimerTask {
  private DateFormat formatter = new SimpleDateFormat("hh:mm:ss a");
  public static void main(String[] args) {
    TimerTask task = new Main();
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(task, new Date(), 1000);
  }
  public void run() {
    System.out.println(formatter.format(new Date()));
  }
}





Create a Timer object

import java.util.Timer;
import java.util.TimerTask;
public class Main {
  Timer timer;
  public Main(int seconds) {
    timer = new Timer();
    timer.schedule(new ToDoTask(), seconds * 1000);
  }
  class ToDoTask extends TimerTask {
    public void run() {
      System.out.println("working");
      timer.cancel(); 
    }
  }
  public static void main(String args[]) {
    new Main(5);
  }
}





Demonstrate Timer and TimerTask.

import java.util.Timer;
import java.util.TimerTask;
class MyTimerTask extends TimerTask {
  public void run() {
    System.out.println("Timer task executed.");
  }
}
class TTest {
  public static void main(String args[]) {
    MyTimerTask myTask = new MyTimerTask();
    Timer myTimer = new Timer();
    myTimer.schedule(myTask, 1000, 500);
    try {
      Thread.sleep(5000);
    } catch (InterruptedException exc) {
    }
    myTimer.cancel();
  }
}





extends TimerTask to create your own task

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.TimerTask;
class MyTask extends TimerTask {
  private DataOutputStream out;
  public MyTask(OutputStream dest) {
    out = new DataOutputStream(dest);
  }
  public void run() {
    try {
      out.writeInt(1);
      out.writeUTF("asdf");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}





Pause and start a timer task

import java.util.Timer;
import java.util.TimerTask;
class MyTask extends TimerTask {
  int counter;
  public MyTask() {
    counter = 0;
  }
  public void run() {
    counter++;
    System.out.println("Ring " + counter);
  }
  public int getCount() {
    return counter;
  }
}
public class Main {
  private boolean running;
  private MyTask task;
  private Timer timer;
  public Main() {
    timer = new Timer(true);
  }
  public boolean isRinging() {
    return running;
  }
  public void startRinging() {
    running = true;
    task = new MyTask();
    timer.scheduleAtFixedRate(task, 0, 3000);
  }
  public void doIt() {
    running = false;
    System.out.println(task.getCount() + " times");
    task.cancel();
  }
  public static void main(String[] args) {
    Main phone = new Main();
    phone.startRinging();
    try {
      System.out.println("started running...");
      Thread.sleep(20000);
    } catch (InterruptedException e) {
    }
    phone.doIt();
  }
}





Schedule a task by using Timer and TimerTask.

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class AutoTask extends TimerTask {
  AutoTask() {
  }
  public void run() {
    System.out.println(new Date());
  }
}
public class Main {
  public static void main(String args[]) {
    AutoTask myTask = new AutoTask();
    Timer bkTimer = new Timer();
    bkTimer.schedule(myTask, 2000, 2000);
    for (int i = 0; i < 5; i++) {
      try {
        Thread.sleep(2100);
      } catch (InterruptedException exc) {
      }
    }
    bkTimer.cancel();
  }
}





Scheduling a Timer Task to Run Repeatedly

import java.util.Timer;
import java.util.TimerTask;
public class Main {
  public static void main(String[] argv) throws Exception {
    int delay = 5000; // delay for 5 sec.
    int period = 1000; // repeat every sec.
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
      public void run() {
        System.out.println("doing"); 
      }
    }, delay, period);
  }
}





Swing also provide a Timer class. A Timer object will send an ActionEvent to the registered ActionListener.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Main implements ActionListener {
  Timer t = new Timer(1000, this);
  Main() {
    t.start();
  }
  public void actionPerformed(ActionEvent e) {
    System.out.println("working");
  }
  public static void main(String args[]) {
    Main main = new Main();
  }
}





Timer and TimerTask Classes

import java.util.Timer;
import java.util.TimerTask;
class GCTask extends TimerTask {
  public void run() {
    System.out.println("Running the scheduled task...");
    System.gc();
  }
}
public class Main {
  public static void main(String[] args) {
    Timer timer = new Timer();
    GCTask task = new GCTask();
    timer.schedule(task, 5000, 5000);
    int counter = 1;
    while (true) {
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
      }
    }
  }
}





Using Timers

The java.util.Timer class provides an alternative way to perform scheduled or recurrent tasks.



import java.util.Timer;
import java.util.TimerTask;
public class MainClass {
  public static void main(String[] args) {
    Timer timer = new Timer();
    timer.schedule(new DisplayQuestionTask(), 0, 10 * 1000);
    try {
      Thread.sleep(10000);
    } catch (InterruptedException e) {
    }
    
    timer.cancel();
    
    
  }
}
class DisplayQuestionTask extends TimerTask {
  int counter = 0;
  public void run() {
    System.out.println(counter++);
  }
}





Your own timer

/*
 * Copyright (c) 1998-2002 Carnegie Mellon University.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS"" AND
 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

import java.util.Vector;
public class Timer {
    int interval;
    boolean periodic;
    boolean isExpired = false;
    static TimerManager manager = new TimerManager ();
    long deadline;
    Timer next, prev;
    public Timer () {
    }
    public void set (int msecDelay, boolean periodic) {
        interval = msecDelay;
        this.periodic = periodic;
        isExpired = false;
        if (!manager.isAlive ()) {
            System.err.println ("TimerManager: restarting");
            manager = new TimerManager ();
        }
        manager.register (this, System.currentTimeMillis () + msecDelay);
    }
    public int getInterval () {
        return interval;
    }
    public boolean getPeriodic () {
        return periodic;
    }
    public void cancel () {
        manager.delete (this);
    }
    protected void alarm () {
    }
    public boolean expired () {
        return isExpired;
    }
        
    /*
    public static void main (String[] args) {
        for (int i=0; i<args.length; ++i) {
            boolean periodic = (args[i].charAt (0) == "p");
            if (periodic) args[i] = args[i].substring (1);
            new TestTimer (args[i], Integer.parseInt (args[i]), periodic);
        }
        while (true) Thread.yield ();
    }
    */
}
class TimerManager extends Thread {
    Timer first, last;
    /*
    static ThreadGroup rootThreadGroup;
    static {
        rootThreadGroup = Thread.currentThread().getThreadGroup();
        while (rootThreadGroup.getParent() != null)
            rootThreadGroup = rootThreadGroup.getParent();
    }
    */
    public TimerManager () {
        super (/* rootThreadGroup, */ "Timer Manager");
        setDaemon (true);
        start ();
    }
    public synchronized void register (Timer t, long deadline) {
        t.deadline = deadline;
        delete (t);  // just in case it"s already registered
        //System.err.println ("TimerManager: set " + t + " to go off at " + deadline);
      insertion: 
        {
            for (Timer u = first; u != null; u = u.next) {
                if (t.deadline < u.deadline) {
                    if (u.prev != null)
                        u.prev.next = t;
                    else
                        first = t;
                    t.prev = u.prev;
                    t.next = u;
                    u.prev = t;
                    break insertion;
                }
            }
            if (last != null) {
                last.next = t;
                t.prev = last;
                t.next = null;
                last = t;
            } else {
                first = last = t;
            }
        }
        //System.err.println ("TimerManager: waking up background thread");
        notifyAll ();
    }
    public synchronized void delete (Timer t) {
        if (t.next != null)
            t.next.prev = t.prev;
        if (t.prev != null)
            t.prev.next = t.next;
        if (t == last)
            last = t.prev;
        if (t == first)
            first = t.next;
        t.next = null;
        t.prev = null;
    }
    static final int FOREVER = 60000;  // wake up at least every 60 seconds
    public synchronized void run () {
        while (true) {
            try {
                //System.err.println ("TimerManager: awake");
                if (first == null) {
                    //System.err.println ("TimerManager: waiting forever");
                    wait (FOREVER);
                    //System.err.println ("TimerManager: woke up");
                }
                else {
                    Timer t = first;
                    long now = System.currentTimeMillis ();
                    if (t.deadline <= now) {
                        // System.err.println ("TimerManager: timer " + t + " just went off at " + now);
                        try {
                            t.isExpired = true;
                            t.alarm ();
                        } catch (Throwable e) {
                            if (e instanceof ThreadDeath)
                                throw (ThreadDeath)e;
                            else
                                e.printStackTrace ();
                        }
                        if (t.periodic) {
                            register (t, now + t.interval);
                        }
                        else {
                            delete (t);
                        }
                    }
                    else {
                        //System.err.println ("TimerManager: waiting for " + (t.deadline - now) + " msec");
                        wait (t.deadline - now);
                        //System.err.println ("TimerManager: woke up");
                    }
                }
            } catch (InterruptedException e) {}
        }
    }
}
/*
class TestTimer extends Timer {
    String message;
    public TestTimer (String message, int millisec, boolean periodic) {
        this.message = message;
        set (millisec, periodic);
    }
    public void alarm () {
        System.out.println (message);
    }
}
*/