¿Cómo usar la clase del temporizador para llamar a un método, hacer algo, reiniciar el temporizador, repetir?

Soy un principiante de Java y he estado dando vueltas con varias soluciones a este problema y me he anudado un poco. Lo intenté con Threads y luego descubrí esta clase de Timer y me he equivocado con ella hasta ahora. Si pudieras publicar código ejecutable con un método principal para poder verlo funcionar y comenzar a jugar desde allí, sería genial.

  1. Lanzamiento del progtwig
  2. llamar a algo doSomething()
  3. Genere un número aleatorio y configure el temporizador por ese tiempo.
  4. Cuando el temporizador se apaga, vuelva a llamar a doSomething() .

Probablemente usando esto: http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html

Si quiere simplemente usar Timer, haría algo como esto:

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

Perdón por la pésima identación.

Además, si necesita progtwigr la ejecución del código, eche un vistazo a los Servicios de Guava, ya que realmente puede hacer que su código sea mucho más claro y abstraer bastante de la repetición de los hilos, la progtwigción, etc.

Por cierto, no me tomé la molestia de generar un número aleatorio, etc., pero creo que puedes descubrir cómo incluir esa parte. Espero que esto sea suficiente para llevarte por el camino correcto.

Para el registro, si usaras guayaba, sería algo como esto:

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

Y simplemente crearía un main que llamó nuevo CrawlingService.start (); Eso es.

¿Desea específicamente un Timer ? Si no, probablemente esté mejor con un ScheduledExecutorService y llame a scheduleAtFixedRate o scheduleWithFixedDelay ; citando los Javadocs :

Java 5.0 introdujo el paquete java.util.concurrent y una de las utilidades de simultaneidad en el mismo es ScheduledThreadPoolExecutor que es un grupo de subprocesos para ejecutar tareas repetidamente a una tasa o retraso dados. Es efectivamente un reemplazo más versátil para la combinación Timer / TimerTask , ya que permite múltiples hilos de servicio, acepta varias unidades de tiempo y no requiere la subclasificación de TimerTask (simplemente implemente Runnable ). Configurar ScheduledThreadPoolExecutor con un hilo lo hace equivalente a Timer .

ACTUALIZAR

Aquí hay algunos códigos de trabajo usando 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); } } 

La salida se ve así:

 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 

Piense en un escenario en el que deseo que mi código se ejecute en un momento determinado de mi aplicación o más tarde a partir de la hora actual. En otras palabras, quiero progtwigr mi tarea en el tiempo definido.

La clase Java Timer (java.util.Timer) permite que una aplicación programe la tarea en una secuencia de fondo separada.

Aquí está el ejemplo más simple de 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 

ANÁLISIS: La llamada a timer.schedule (task, 10000,1000) va a progtwigr la tarea que se va a ejecutar por primera vez (en otro hilo) después de 10 segundos desde esta llamada. Después de eso, volverá a llamar después de un retraso de 10 segundos. Es importante mencionar aquí que si la tarea no se puede iniciar después de 10 segundos, la próxima llamada a la tarea no se realizará antes del estanque. Entonces aquí el tiempo de demora entre dos tareas consecutivas es fijo.

Fuente: Ejemplo del temporizador de Java

Esta página tiene un buen ejemplo del uso de Timer y TimerTask que puede ajustar según sus necesidades.

Si no quieres usar la clase de temporizador y puedes usar Quartz, entonces hazlo como. Mi clase principal sería

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

y la clase de trabajo sería

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

java -jar .. & un jar ejecutable para esto y comenzaría esto usando java -jar .. & y Ctrl+C puede detener ese proceso, si lo quiere en segundo plano, disown

El siguiente código se ejecutará a las 18:20 y se repetirá en intervalos de 5 segundos.

 public static void main(String[] args) { Timer timer = new Timer(); TimerTask tt = new TimerTask() { public void run() { Calendar cal = Calendar.getInstance(); int hour = cal.get(Calendar.HOUR_OF_DAY); int min = cal.get(Calendar.MINUTE); if (hour == 18 && min == 20) { doSomething(); } } }; timer.schedule(tt, 1000, 5000); }