Esempio n. 1
0
  /**
   * Schedule the specified timer task for execution at the specified time with the specified
   * period, in milliseconds. If period is positive, the task is scheduled for repeated execution;
   * if period is zero, the task is scheduled for one-time execution. Time is specified in
   * Date.getTime() format. This method checks timer state, task state, and initial execution time,
   * but not period.
   *
   * @param task task to be scheduled.
   * @param userTime the user time at which task is to be executed or <tt>null</tt> if the delay is
   *     specified
   * @param delay the delay in milliseconds before the task execution
   * @param period time in milliseconds between successive task executions.
   * @param isUserClock true if the time is bound to user clock
   * @throws IllegalArgumentException if <tt>time()</tt> is negative.
   * @throws IllegalStateException if task was already scheduled or cancelled, timer was cancelled,
   *     or timer thread terminated.
   */
  private void sched(TimerTask task, Date userTime, long delay, long period) {
    final boolean isUserClock = userTime != null;

    long time;

    if (isUserClock) {
      long t = userTime.getTime();
      if (t < 0) {
        throw new IllegalArgumentException("Illegal execution time.");
      }
      time = Timer.userTimeFromStart(t);
    } else {
      time = Timer.monotonicTimeFromStart(JVM.monotonicTimeMillis() + delay);
    }

    synchronized (queue) {
      if (!queue.newTasksMayBeScheduled) {
        throw new IllegalStateException("Timer already cancelled.");
      }

      /*
       * If the TimerThread has exited without an error
       * it is restarted. See the commentary in TimerThread.run.
       */
      if (thread == null || !thread.isAlive()) {
        thread = new TimerThread(queue);
        thread.start();
      }

      synchronized (task.lock) {
        if (task.state != TimerTask.VIRGIN) {
          throw new IllegalStateException("Task already scheduled or cancelled");
        }
        task.nextExecutionTime = time;
        task.period = period;
        task.state = TimerTask.SCHEDULED;
        task.isUserClock = isUserClock;
      }

      queue.add(task);
      if (queue.getMin() == task) queue.notify();
    }
  }