Je suis un débutant en Java et j'ai essayé différentes solutions à ce problème et je me suis un peu fait. J'ai essayé avec Threads, puis découvert cette classe Timer et je l'ai bousillé sans succès jusqu'à présent. Si vous pouviez publier code exécutable avec une méthode principale pour que je puisse le voir fonctionner et commencer à jouer à partir de là, ce serait formidable.
doSomething()
doSomething()
.Probablement en utilisant ceci: http://docs.Oracle.com/javase/6/docs/api/Java/util/Timer.html
Si vous voulez simplement utiliser Timer, je ferais quelque chose comme ceci:
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
}
}
Désolé pour l'identification moche.
De même, si vous avez besoin de planifier l'exécution du code, jetez un coup d'œil à Guava Services , car cela peut vraiment rendre votre code beaucoup plus clair et abstrait, ce qui en fait un peu le pilier de la création de threads, de la planification, etc.
En passant, je n'ai pas pris la peine de générer des nombres aléatoires, etc., mais je pense que vous pouvez comprendre comment inclure cette partie. J'espère que cela suffit pour vous mettre sur la bonne voie.
Pour mémoire, si vous utilisiez du goyave, cela ressemblerait à ceci:
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);
}
};
}
}
Et vous créeriez simplement un principal appelé new CrawlingService.start (); c'est tout.
Voulez-vous spécifiquement une Timer
? Sinon, vous êtes probablement mieux avec un ScheduledExecutorService et l'appel de scheduleAtFixedRate
ou scheduleWithFixedDelay
; citant le Javadocs :
Java 5.0 a introduit le paquetage
Java.util.concurrent
et l’un des fichiers les utilitaires de simultanéité qui y figurent est laScheduledThreadPoolExecutor
qui est un pool de threads pour l'exécution répétée de tâches à un taux donné ou retard. C'est effectivement un remplacement plus polyvalent pour leTimer
TimerTask
COMBINAISON, CAR ELLE PERMET PLUSIEURS THREADS DE SERVICE, ACCEPTE DIFFÉRENTES UNITÉS DE TEMPS ET NE NÉCESSITE PAS DE SOUS-CLASSETimerTask
(IMPLÉMENTEZ SIMPLEMENTRunnable
). CONFIGURATION DEScheduledThreadPoolExecutor
AVEC UN THREAD LE REND ÉQUIVALENT ÀTimer
.
_/ _ METTRE À JOUR
Voici un code de travail utilisant une 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 sortie ressemble à:
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
Imaginez un scénario dans lequel je veux que mon code soit exécuté à un moment donné dans mon application ou à un moment ultérieur par rapport à l'heure actuelle. En d'autres termes, je veux planifier ma tâche à l'heure définie.
La classe Java Timer (Java.util.Timer) permet à une application de planifier la tâche sur un thread en arrière-plan distinct.
Voici le exemple le plus 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
ANALYSE: L'appel à timer.schedule (tâche, 10000,1000) va planifier la tâche qui va s'exécuter pour la première fois (sur un autre thread) après 10 secondes à compter de cet appel. Ensuite, il appellera à nouveau après un délai de 10 secondes. Il est important de mentionner ici que si la tâche ne peut pas être démarrée après 10 secondes, le prochain appel de tâche n'aura pas lieu avant le début de la migration. Donc, ici, le délai entre deux tâches consécutives est fixé.
Source: Exemple de minuteur Java
Si vous ne souhaitez pas utiliser la classe timer et que vous pouvez utiliser Quartz, procédez comme suit. Ma classe principale serait
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();
}
}
}));
}
}
et la classe d'emploi serait
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!");
}
}
Je voudrais créer un fichier jar exécutable pour cela et le démarrer en utilisant Java -jar .. &
et Ctrl+C
peut arrêter ce processus, si vous le souhaitez en arrière-plan disown
it
Cette page présente un bon exemple d'utilisation de Timer
s et de TimerTask
s que vous pouvez adapter à vos besoins.
Le code ci-dessous s'exécutera à 18h20 et se répétera dans un intervalle de 5 secondes.
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);
}