ScalableTimer.java :  » Ajax » zk » org » zkoss » util » Java Open Source

Java Open Source » Ajax » zk 
zk » org » zkoss » util » ScalableTimer.java
/* ScalableTimer.java

  Purpose:
    
  Description:
    
  History:
    Wed Dec  5 14:09:13     2007, Created by tomyeh

Copyright (C) 2007 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
  This program is distributed under LGPL Version 3.0 in the hope that
  it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/
package org.zkoss.util;

import java.util.Date;
import java.util.Timer;

/**
 * A facility for threads to schedule tasks for future execution in
 * a background thread.
 * It has the same function as {@link Timer}, but it is scalable by use of
 * a collection of {@link Timer}. Use {@link ScalableTimer} if you want to
 * schedule a lot of tasks.
 * However, it doesn't support repeated execution.
 *
 * @author tomyeh
 * @since 3.0.1
 */
public class ScalableTimer {
  private final ScalableTimerInfo[] _tis;
  private int _threshold;

  /** Creates a scalable timer.
   *
   * <p>Note: no real timer (thread) is created until the first task
   * being scheduled.
   *
   * @param cTimers the maximal allowed number of timers to use.
   * 1 is assumed if nonpositive.
   * @param threshold the threshold, i.e., the number of tasks allowed to
   * be scheduled for a timer before creating additional timer.
   * 1 is assumed if nonpositive.
   * Note: if the number of scheduled task exceeds the capacity
   * ({@link #getMaxTimerSize} * {@link #getThreshold}), the tasks are distributed evenly
   * over all timers
   */
  public ScalableTimer(int cTimers, int threshold) {
    if (cTimers <= 0) cTimers = 1;
    if (threshold <= 0) threshold = 1;

    _tis = new ScalableTimerInfo[cTimers];
    for (int j = cTimers; --j >= 0;)
      _tis[j] = new ScalableTimerInfo();
    _threshold = threshold;
  }

  /** Returns the maximal allowed number of timers ({@link Timer})
   * are used in this instance.
   */
  public int getMaxTimerSize() {
    return _tis.length;
  }
  /** Returns the threshold, i.e., the allowed number of tasks to be
   * scheduled for a timer, before starting a new timer.
   */
  public int getThreshold() {
    return _threshold;
  }

  /** Terminates this timer, discarding any currently scheduled tasks.
   * This method may be called repeatedly; the second and subsequent calls have no effect.
   */
  public void cancel() {
    for (int j = _tis.length; --j >= 0;) {
      final ScalableTimerInfo ti = _tis[j];
      synchronized (ti) {
        if (ti.timer != null) {
          ti.timer.cancel();
          ti.timer = null;
        }
        ti.count = 0;
      }
    }
  }
 
  /** Schedules the specified task for execution after the specified delay.
   * @param task task to be scheduled.
   * @param delay delay in milliseconds before task is to be executed.
   */
  public void schedule(ScalableTimerTask task, long delay) {
    getInfo(task).timer.schedule(task, delay);
  }
  /** Schedules the specified task for execution at the specified time.
   * @param task task to be scheduled.
     * @param time time at which task is to be executed.
   */
  public void schedule(ScalableTimerTask task, Date time) {
    getInfo(task).timer.schedule(task, time);
  }

  private ScalableTimerInfo getInfo(ScalableTimerTask task) {
    //No sync to select a proper ti since it is ok to race
    ScalableTimerInfo ti = null;
    for (int j = _tis.length; --j >= 0;) {
      if (_tis[j].count < _threshold) {
        ti = _tis[j];
        break; //found
      }
      if (ti == null || ti.count > _tis[j].count)
        ti = _tis[j];
    }

    synchronized (ti) {
      ++ti.count;
      if (ti.timer == null)
        ti.timer = new Timer(true);
    }
    task.setScalableTimerInfo(ti);
    return ti;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.