Domanda

Mi piacerebbe avere un java.utils.Timer con un ripristinabile tempo in java.Ho bisogno di impostare una volta che l'evento si verifichi in X secondi.Se non accade nulla tra il momento in cui il timer è stato creato e X secondi, poi si verifica l'evento come di consueto.

Se, tuttavia, prima di X secondi ha trascorso il tempo, ho deciso che l'evento dovrebbe verificarsi dopo Y secondi, invece, allora voglio essere in grado di dire che il timer si azzera il tempo, in modo che l'evento si verifica in Y secondi.E. g.il timer deve essere in grado di fare qualcosa di simile:

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).

Non vedo un modo per fare questo utils timer, come se si chiama annulla() che non è possibile pianificare di nuovo.

L'unico modo che ho di venire vicino a replicare questo comportamento è utilizzando javax.swing.Timer e comporta l'arresto l'originale timer, e la creazione di uno nuovo.cioè:

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

C'è un modo più semplice??

È stato utile?

Soluzione

Secondo il Timer la documentazione, in Java 1.5 in poi, si dovrebbe preferire il ScheduledThreadPoolExecutor invece.(Si può creare questo esecutore utilizzando Executors.newSingleThreadScheduledExecutor() per facilità di uso;crea qualcosa di molto simile a un Timer.)

Il bello è che, quando si pianifica un'attività (chiamando schedule()), restituisce un ScheduledFuture oggetto.È possibile utilizzare questo per annullare l'operazione pianificata.Siete quindi liberi di presentare una nuova attività con un diverso tempo di attivazione.

ETA:Il Timer documentazione legata a non dire nulla ScheduledThreadPoolExecutor, tuttavia il OpenJDK versione ebbe a dire:

Java 5.0, che ha introdotto il java.util.concurrent pacchetto e uno della concorrenza utilità in esso la ScheduledThreadPoolExecutor che è un thread aperto per più volte l'esecuzione di attività ad un tasso o di ritardo.Si tratta in effetti di una più versatile per la sostituzione Timer/TimerTask combinazione, in quanto consente a più thread di servizio, accetta tutti i tipi di unità di tempo, e non richiede la creazione di sottoclassi TimerTask (solo implementare Runnable).Configurazione ScheduledThreadPoolExecutor con un thread rende equivalente a Timer.

Altri suggerimenti

Se il vostro Timer è sempre e solo andando ad avere un compito da eseguire, quindi vorrei suggerire la creazione di sottoclassi è:

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

Sarà necessario lavorare sul codice per aggiungere controlli per mis-uso, ma dovrebbe ottenere quello che vuoi.Il ScheduledThreadPoolExecutor non sembra avere un supporto integrato per la riprogrammazione delle attività esistenti, ma un simile approccio dovrebbe funzionare anche lì.

Tutto il frammento di Codice è questa ....Spero possa essere di aiuto completo

{

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


}

Non è necessario pianificare un'attività ricorrente?In quel caso mi consiglia di considerare l'utilizzo di Quarzo.

Io non credo che sia possibile farlo Timer/TimerTask, ma a seconda di che cosa esattamente si vuole ottenere si potrebbe essere felici con l'utilizzo di java.util.concurrent.ScheduledThreadPoolExecutor.

questo è quello che sto provando.Ho una classe che esegue il polling di un database ogni 60 secondi con un TimerTask.

nella mia classe principale, mi tengo l'istanza del Timer, e un esempio del mio locale sottoclasse di TimerTask.la classe principale dispone di un metodo per impostare l'intervallo di polling (diciamo che va da 60 a 30).in esso, voglio annullare la mia TimerTask (che è la mia classe, dove ho sovrascritto il metodo cancel() per fare un po ' di pulizia, ma non importa) e quindi renderlo nullo.ho ricreato una nuova istanza, e pianificare la nuova istanza presso il nuovo intervallo del Timer.

dal momento che il Timer non è annullato, il thread è stato utilizzato rimane attivo (e così per qualsiasi altro TimerTasks al suo interno), e il vecchio TimerTask viene sostituito con uno nuovo, che succede ad essere la stessa, ma la VIRGIN (visto che il precedente sarebbe stata eseguita o eseguita in modo pianificato, non è più VERGINE, come richiesto per la pianificazione).

quando voglio spegnere l'intero timer, annullare e null il TimerTask (come ho fatto io quando cambiare il timing, di nuovo, per la pulitura delle risorse nel mio sottoclasse di TimerTask), e quindi annullare e azzerare il Timer stesso.

Ecco un esempio per Risettabile Timer .Provare a modificare l'impostazione per la vostra 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));
    }
}

Questo esempio stampa la data e l'ora correnti per ogni 5 secondi...Ma se si dà alcun input da console il timer sarà ritardata per eseguire l'ingresso, con attività...

Ho fatto una propria classe timer per un simile scopo;sentitevi liberi di usare:

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);
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top