2012-02-23 9 views
22

Sono un principiante di Java e ho iniziato a vaneggiare con varie soluzioni a questo problema e mi sono fatto un po 'annodato. Ho provato con Threads e poi ho scoperto questa classe di Timer e l'ho giocoforza senza successo fino ad ora. Se potessi pubblicare il codice eseguibile con un metodo principale in modo che potessi vederlo funzionare e iniziare a giocare da lì, sarebbe fantastico.Come utilizzare la classe Timer per chiamare un metodo, fare qualcosa, resettare il timer, ripetere?

  1. programma di lancio
  2. chiamata doSomething()
  3. Genera numeri casuali e impostare il timer per così tanto tempo.
  4. Quando il timer si spegne, chiamare di nuovo doSomething().

Probabilmente utilizzare questo: http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html

+0

Non farlo con il timer. Utilizzare qualcosa da java.util.concurrent. È più facile da capire, più performante e più robusto. L'esempio di SimonC di seguito è un modo decente per farlo. – kittylyst

risposta

32

Se si desidera usare semplicemente Timer, lo farei fai qualcosa del genere:

public class TestClass { 
    public long myLong = 1234; 

    public static void main(String[] args) { 
     final TestClass test = new TestClass(); 

     Timer timer = new Timer(); 
     timer.schedule(new TimerTask() { 

      @Override 
      public void run() { 
       test.doStuff(); 
      } 
     }, 0, test.myLong); 
    } 

    public void doStuff(){ 
     //do stuff here 
    } 
} 

Siamo spiacenti per l'identificazione pessima.

Inoltre, se avete bisogno di pianificare l'esecuzione di codice, dare un'occhiata a Guava Services dal momento che può davvero rendere il codice molto più chiara e astratto di un bel po 'di testo standard di creare discussioni, la programmazione, ecc

By A proposito, non mi sono preso la briga di generare un numero casuale, ecc., ma penso che tu possa capire come includere quella parte. Spero che questo sia sufficiente per portarti sulla buona strada.

Per la cronaca, se si sceglie di usare Guava, che sarebbe simile a questa:

class CrawlingService extends AbstractScheduledService { 

    @Override 
    protected void runOneIteration() throws Exception { 
     //run this alot 
    } 

    @Override 
    protected void startUp() throws Exception { 
     //anything you need to step up 
    } 

    @Override 
    protected void shutDown() throws Exception { 
     //anything you need to tear down 
    } 


    @Override 
    protected Scheduler scheduler() { 
     return new CustomScheduler() { 
      @Override 
      protected Schedule getNextSchedule() throws Exception { 
       long a = 1000; //number you can randomize to your heart's content 
       return new Schedule(a, TimeUnit.MILLISECONDS); 
      } 
     }; 
    } 
} 

E si sarebbe semplicemente creare un principale che chiama nuova CrawlingService.start(); questo è tutto.

0

This page ha un buon esempio di utilizzo Timer s e TimerTask s che è possibile mettere a punto per le vostre esigenze.

22

Vuoi specificamente uno Timer? Altrimenti probabilmente starai meglio con uno ScheduledExecutorService e chiamando lo scheduleAtFixedRate o scheduleWithFixedDelay; citando il Javadocs:

Java 5.0 introdotto il pacchetto java.util.concurrent e uno dei utilità concorrenza ivi è la ScheduledThreadPoolExecutor che è un pool di thread per eseguire ripetutamente attività in un determinato tasso o ritardo. È effettivamente una sostituzione più versatile per la combinazione Timer/TimerTask, in quanto consente a più thread di servizio, accetta varie unità di tempo, e non richiede sottoclassi TimerTask (solo implementare Runnable). La configurazione di con un thread lo rende equivalente a Timer.

UPDATE

Ecco alcuni codice di lavoro utilizzando un ScheduledExecutorService:

import java.util.Date; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

public class Test { 
    public static void main(String[] args) { 
     final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(); 
     ses.scheduleWithFixedDelay(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println(new Date()); 
      } 
     }, 0, 1, TimeUnit.SECONDS); 
    } 
} 

L'uscita sembra:

Thu Feb 23 21:20:02 HKT 2012 
Thu Feb 23 21:20:03 HKT 2012 
Thu Feb 23 21:20:04 HKT 2012 
Thu Feb 23 21:20:05 HKT 2012 
Thu Feb 23 21:20:06 HKT 2012 
Thu Feb 23 21:20:07 HKT 2012 
2

Pensa a uno scenario in cui desidero che il mio codice venga eseguito in un determinato momento nella mia applicazione o in un momento successivo dall'ora corrente. In altre parole, voglio programmare il mio compito in un momento preciso.

Java Timer classe (java.util.Timer) consente a un'applicazione di pianificare l'attività su un thread in background separato.

Qui è il più semplice example of Java Timer:

import java.util.Timer; 
import java.util.TimerTask; 
public class JavaTimer { 
    public static void main(String[] args){ 
    Timer timer = new Timer(); 
    TimerTask task = new TimerTask() { 
     @Override 
    public void run() { 
    System.out.println("Inside Timer Task" + System.currentTimeMillis()); 
     } 
    }; 

    System.out.println("Current time" + System.currentTimeMillis()); 
    timer.schedule(task, 10000,1000); 
    System.out.println("Current time" + System.currentTimeMillis()); 

    } 
} 

Output: 
Current time1455469505220 
Current time1455469505221 
Inside Timer Task1455469515222 
Inside Timer Task1455469516222 
Inside Timer Task1455469517222 
Inside Timer Task1455469518222 
Inside Timer Task1455469519222 
Inside Timer Task1455469520222 
Inside Timer Task1455469521222 
Inside Timer Task1455469522222 
Inside Timer Task1455469523222 
Inside Timer Task1455469524222 
Inside Timer Task1455469525222 
Inside Timer Task1455469526222 
Inside Timer Task1455469527222 
Inside Timer Task1455469528223 
Inside Timer Task1455469529223 and it goes on 

ANALISI: La chiamata a timer.schedule (compito, 10000,1000) sta per pianificare l'attività che sta per eseguire per la prima volta (su un altro thread) dopo 10 secondi da questa chiamata. Dopodiché chiamerà di nuovo dopo un ritardo di 10 secondi. È importante menzionare qui che se l'attività non può essere avviata dopo 10 secondi, la prossima chiamata all'attività non otterrà il prelavaggio. Quindi qui il tempo di ritardo tra due attività consecutive è fisso.

Fonte: Java Timer Example

0

Se non si desidera utilizzare la classe timer e possibile utilizzare quarzo quindi eseguire piace. La mia classe principale sarebbe

import com.google.common.util.concurrent.AbstractScheduledService; 
import org.quartz.CronScheduleBuilder; 
import org.quartz.JobBuilder; 
import org.quartz.JobDetail; 
import org.quartz.impl.StdSchedulerFactory; 
import org.quartz.*; 
import org.quartz.impl.StdSchedulerFactory; 
import static org.quartz.TriggerBuilder.newTrigger; 

import java.util.concurrent.CountDownLatch; 

public class Test { 


    public static void main(String[] args) throws Exception{ 


     CountDownLatch latch = new CountDownLatch(1); 


     //do schdeuling thing 
     JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity(
       "CronQuartzJob", "Group").build(); 

     // Create a Trigger that fires every 5 minutes. 
     Trigger trigger = newTrigger() 
       .withIdentity("TriggerName", "Group") 
       .withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?")) 
       .build(); 

     // Setup the Job and Trigger with Scheduler & schedule jobs 
     final Scheduler scheduler = new StdSchedulerFactory().getScheduler(); 
     scheduler.start(); 
     scheduler.scheduleJob(job, trigger); 

     // 
     latch.await(); 

     Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        scheduler.shutdown(); 
        latch.countDown(); 
       }catch (Exception e){ 
        e.printStackTrace(); 
       } 
      } 
     })); 

    } 






} 

e la classe lavoro sarebbe

import org.quartz.Job; 
import org.quartz.JobExecutionContext; 
import org.quartz.JobExecutionException; 

public class SimpleJob implements Job { 


    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 
     System.out.println("executing task!"); 
    } 


} 

vorrei creare un jar eseguibile per questo e iniziare questa utilizzando java -jar .. & e Ctrl+C può fermare questo processo, se lo volete in background disown it