2010-11-23 10 views
3

Ich habe ein wenig Arbeit geleistet, um einige Daten von einem Webdienst abzurufen, aber jetzt habe ich das Problem, Anfragen an sie zu planen, und ich bin mir nicht sicher, wo ich anfangen soll.Wie ist die Aufgabenplanung implementiert?

Ich höre eine JMS-Warteschlange für Ereignisse und nach Erhalt eines Ereignisses muss ich eine Anfrage an den Web-Service nach einer bestimmten Zeit. Die Dauer hängt von den Ereignisattributen ab. Wenn der Webdienst false zurückgibt, muss ich weiterhin Anforderungen planen, bis der Wert true lautet.

Ich dachte über das Erstellen einer Nachschlageanforderung in einer Warteschlange nach dem Empfang eines Ereignisses oder einer falschen Antwort, aber das scheint nicht ideal - ich würde ständig Nachrichten konsumieren und die Zeit überprüfen, um zu sehen, ob eine Anfrage sollte noch gemacht werden und es in die Warteschlange zurückstellen, wenn nicht.

Wenn jemand Ratschläge zur Umsetzung eines solchen Problems hat, würde ich es sehr zu schätzen wissen.

Antwort

0

Ich habe beschlossen, mit Spring Task Scheduling zu gehen, die in der Version eingeführt wurde 3. Es bietet Pooling, Planung basierend auf den beiden Zeitpunkten in der Zeit und Intervalle, und wenn mehr Anpassungs es einen cron-Option erforderlich ist. Ich habe mich nicht in die Tiefen dessen vertieft, was mit Quartz erreicht werden kann, aber es bietet auch eine Integration damit.

2

eine bestehende OSS-Scheduler verwenden: http://java-source.net/open-source/job-scheduler

Sie immer rollen können Sie besitzen, aber ich würde es nicht empfehlen.

Ein wichtiges Merkmal eines Schedulers sollte sein, dass es Neustart/Absturz überlebt.

5

Stellen Sie zuerst sicher, dass Sie die Ereignisse in der Warteschlange in der Reihenfolge aufbewahren, in der sie ausgeführt werden müssen. Dadurch wird sichergestellt, dass Sie nur den Kopf der Warteschlange anzeigen müssen, um zu sehen, wann das nächste Ereignis geplant werden sollte. Sie können hierfür eine PriorityQueue verwenden.

Ihr Thread für die Verarbeitung von Ereignissen fragt Elemente in dieser Warteschlange ab und verarbeitet sie. Werfen Sie einen Blick auf das Hauptelement und sehen Sie, wann das nächste Ereignis ausgeführt werden muss. Wählen Sie ein Objekt aus, das als Sperrobjekt verwendet werden soll, und rufen Sie den Hauptthread Object.wait(long) für dieses Objekt auf, wobei Sie die Methode die Anzahl der Millisekunden übergeben, bis das nächste Ereignis ausgeführt werden muss.

Wenn ein neuer Thread eingeht, fügen Sie ihn an der entsprechenden Stelle in die Warteschlange ein. Wenn sich das Element an der Spitze der Warteschlange befindet, bedeutet dies, dass der Thread früher aufwachen muss. Rufen Sie das Sperrobjekt Object.notifyAll() auf, um den Verarbeitungsthread zu aktivieren. Es wird sehen, dass es nichts zu verarbeiten gibt und für die entsprechende Zeit wieder schlafen geht.

 
public class ProcessingQueue extends Thread { 

    private PriorityQueue<Task> tasks; 

    private volatile boolean isRunning = true; 

    public void addTask(Task t) { 
    synchronized (this.tasks) { 
     this.tasks.offer(t); 
     // this call requires synchronization to this.tasks 
     this.tasks.notifyAll(); 
    } 
    } 

    public void shutdown() { 
    this.isRunning = false; 
    synchronized (this.tasks) { 
     this.notifyAll(); 
    } 
    } 

    public void run() { 
    while (this.isRunning) { 
     synchronized (this.tasks) { 
     Task t = this.tasks.peek(); 
     // by default, if there are no tasks, this will wake every 60 seconds 
     long millisToSleep = 60000; 
     // getExecuteMillis() should return the time, in milliseconds, for execution 
     if (t != null) millisToSleep = t.getExecuteMillis() - System.currentTimeMillis(); 
     if (millisToSleep > 0) { 
      try { 
      // this line requires synchronization to this.tasks 
      // and the lock is removed while it waits 
      this.tasks.wait(millisToSleep); 
      } catch (InterruptedException e) { 
      } 
     } 
     t = this.tasks.poll(); 
     if (t != null) { 
      t.execute(); 
     } 
     } 
    } 
    } 
} 
+0

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/DelayQueue.html Sehen Sie sich Java Delay Queue an. Sehr geeignet für zeitbasierte Aufgabenwarteschlangen. Hier ist der Quellcode http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent/DelayQueue.java#DelayQueue.take%28%29 – Anshul

Verwandte Themen