Сбрасываемый Java Таймер

голоса
36

Я хотел бы иметь java.utils.Timer с возвратным временем в java.I необходимо установить один раз от события происходит в Х секундах. Если ничего не происходит в промежутке времени создания таймера и X секунд, то событие происходит в обычном режиме.

Если, однако, прежде чем Х секунд прошло, я решил, что это событие должно произойти после Y секунд вместо, то я хочу, чтобы быть в состоянии сказать, таймер, чтобы сбросить свое время так, что событие происходит в Y секунд. Например, таймер должен быть в состоянии сделать что-то вроде:

Timer timer = new Timer();  
timer.schedule(timerTask, 5000); //Timer starts in 5000 ms (X)

//At some point between 0 and 5000 ms...  
setNewTime(timer, 8000);  //timerTask will fire in 8000ms from NOW (Y).

Я не вижу способ сделать это с помощью таймера утилитами, как если вы звоните отменить () вы не можете запланировать его снова.

Единственный способ, которым я пришел близко к репликации это поведение является использование javax.swing.Timer и включает в себя останавливать оригинальный таймер, и создание нового. то есть:

timer.stop();
timer = new Timer(8000, ActionListener);
timer.start();

Есть более простой способ ??

Задан 28/08/2008 в 11:38
источник пользователем
На других языках...                            


8 ответов

голоса
48

Согласно Timerдокументации, в Java 1.5 года, вы должны предпочесть ScheduledThreadPoolExecutorвместо этого. (Вы можете , как создать этот исполнитель , используя для простоты использования, он создает что - то так же, как .)Executors.newSingleThreadScheduledExecutor()Timer

Отличная вещь, когда вы планируете задачу (по телефону schedule()), он возвращает ScheduledFutureобъект. Вы можете использовать это , чтобы отменить запланированное задание. Вы тогда свободны представить новую задачу с различным временем срабатывания.

ETA: Timerдокументация связана с ничего не говорит о том ScheduledThreadPoolExecutor, однако OpenJDK версия имела это сказать:

Java 5.0 представил java.util.concurrentпакет и одну из утилит для параллелизма в нем является ScheduledThreadPoolExecutorчто пул потоков для повторного выполнения задач при заданной скорости или задержке. Это эффективно более универсальна замена Timer/ TimerTask комбинации, так как она позволяет несколько потоков услуг, принимает различные единицы времени, и не требует подклассов TimerTask(просто реализовать Runnable). Настройка ScheduledThreadPoolExecutorс одним потоком делает его эквивалент Timer.

Ответил 28/08/2008 в 12:52
источник пользователем

голоса
17

Если ваш Timerтолько когда - либо будет иметь одну задачу выполнить , то я хотел бы предложить подклассов его:

import java.util.Timer;
import java.util.TimerTask;

public class ReschedulableTimer extends Timer
{
    private Runnable  task;
    private TimerTask timerTask;

    public void schedule(Runnable runnable, long delay)
    {
        task = runnable;
        timerTask = new TimerTask()
        {
            @Override
            public void run()
            {
                task.run();
            }
        };
        this.schedule(timerTask, delay);
    }

    public void reschedule(long delay)
    {
        timerTask.cancel();
        timerTask = new TimerTask()
        {
            @Override
            public void run()
            {
                task.run();
            }
        };
        this.schedule(timerTask, delay);
    }
}

Вам нужно будет работать над кодом , чтобы добавить проверку для неправильного использования, но она должна достичь того, чего вы хотите. ScheduledThreadPoolExecutor, Кажется, не имеет встроенную поддержку для перепланирования существующих задач , как, но подобный подход должен работать там.

Ответил 28/08/2008 в 13:25
источник пользователем

голоса
3

Весь Фрагмент кода идет как это .... Я надеюсь, что это будет способствовать полной

{

        Runnable r = new ScheduleTask();
        ReschedulableTimer rescheduleTimer = new ReschedulableTimer();
        rescheduleTimer.schedule(r, 10*1000);


    public class ScheduleTask implements Runnable {
        public void run() {
            //Do schecule task

        }
      }


class ReschedulableTimer extends Timer {
        private Runnable task;
        private TimerTask timerTask;

        public void schedule(Runnable runnable, long delay) {
          task = runnable;
          timerTask = new TimerTask() { 
              public void run() { 
                  task.run(); 
                  }
              };

          timer.schedule(timerTask, delay);        
        }

        public void reschedule(long delay) {
            System.out.println("rescheduling after seconds "+delay);
          timerTask.cancel();
          timerTask = new TimerTask() { 
              public void run() { 
                  task.run(); 
              }
          };
          timer.schedule(timerTask, delay);        
        }
      }


}
Ответил 27/11/2012 в 12:40
источник пользователем

голоса
1

это то, что я попробовать. У меня есть класс, который опрашивает базу данных каждые 60 секунд с помощью TimerTask.

в моем главном классе, я храню экземпляр Timer, и экземпляр моего местного подкласса TimerTask. основной класс имеет метод, чтобы установить интервал опроса (скажем, происходит от 60 до 30 лет). в нем, я отменить TimerTask (который мой подкласс, где я переписал метод отмены (), чтобы сделать некоторые очистки, но это не имеет значения), а затем сделать его недействительным. я воссоздать новый экземпляр этого, и запланировать новый экземпляр на новом интервале в существующем таймере.

так как сам таймер не будет отменен, нить он использовал остается активным (и так и любые другие TimerTasks внутри него), а старый TimerTask заменяется на новый, который бывает то же самое, но ДЕВЫ (так старый был бы выполнен или по расписанию, он уже не девственник, как это требуется для планирования).

когда я хочу выключать весь таймер, я отменить и обнулить TimerTask (такой же, как я делал при изменении времени, опять же, для очистки ресурсов в моем подклассе TimerTask), а затем я отменить и нуль самого таймера.

Ответил 16/04/2009 в 15:09
источник пользователем

голоса
1

Я не думаю , что это возможно сделать это с Timer/TimerTask, но в зависимости от того, что именно вы хотите достичь , вы можете быть счастливы с использованием java.util.concurrent.ScheduledThreadPoolExecutor.

Ответил 28/08/2008 в 12:47
источник пользователем

голоса
1

Вы должны запланировать повторяющуюся задачу делать? В этом случае я рекомендую вам рассмотреть возможность использования Quartz .

Ответил 28/08/2008 в 11:54
источник пользователем

голоса
0

Я сделал собственный класс таймера для аналогичных целей; не стесняйтесь использовать его:

public class ReschedulableTimer extends Timer {
  private Runnable mTask;
  private TimerTask mTimerTask;

  public ReschedulableTimer(Runnable runnable) {
    this.mTask = runnable;
  }

  public void schedule(long delay) {
    if (mTimerTask != null)
      mTimerTask.cancel();

    mTimerTask = new TimerTask() {
      @Override
      public void run() {
        mTask.run();
      }
    };
    this.schedule(mTimerTask, delay);
  }
}
Ответил 20/07/2018 в 16:33
источник пользователем

голоса
0

Вот пример для сбрасываемого таймера. Попробуйте изменить его для convinence ...

package com.tps.ProjectTasks.TimeThread;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Simple demo that uses java.util.Timer to schedule a task to execute
 * every 5 seconds and have a delay if you give any input in console.
 */

public class DateThreadSheduler extends Thread {  
    Timer timer;
    BufferedReader br ;
    String data = null;
    Date dNow ;
    SimpleDateFormat ft;

    public DateThreadSheduler() {

        timer = new Timer();
        timer.schedule(new RemindTask(), 0, 5*1000); 
        br = new BufferedReader(new InputStreamReader(System.in));
        start();
    }

    public void run(){

        while(true){
            try {
                data =br.readLine();
                if(data != null && !data.trim().equals("") ){
                    timer.cancel();
                    timer = new Timer();
                    dNow = new Date( );
                    ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
                    System.out.println("Modified Current Date ------> " + ft.format(dNow));
                    timer.schedule(new RemindTask(), 5*1000 , 5*1000);
                }

            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) {
        System.out.format("Printint the time and date was started...\n");
        new DateThreadSheduler();
    }
}

class RemindTask extends TimerTask {
    Date dNow ;
    SimpleDateFormat ft;

    public void run() {

        dNow = new Date();
        ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
        System.out.println("Current Date: " + ft.format(dNow));
    }
}

Этот пример выводит текущую дату и время на каждые 5 секунд ... Но если вы дадите какой-либо вход в консоли таймер будет задерживаться, чтобы выполнить данную задачу ввода ...

Ответил 05/12/2012 в 10:53
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more