1. #1
    Cadet 4th Year
    Dabei seit
    Jun 2010
    Beiträge
    127

    [Java] Methode zu bestimmter Uhrzeit starten

    Nabend Leute,
    ich arbeite an einem kleinen Programm das mehrere Wochen auf einem Server laufen soll und zu 6 verschiedenen Tageszeiten eine bestimmte Methode starten soll. Die Ausführung der Methode dauert dann ca 15min. Danach soll das Programm dann im Idle warten bis die nächste Ausführungszeit erreicht ist. Ich habe über google bereits die Timer Class gefunden, konnte das jedoch nicht richtig auf meine Bedürfnisse anpassen. Fällt euch noch eine andere Variante ein bzw. hat jmd ein Tutorial zur Hand in dem mein Fall ungefähr behandelt wird?

    Cheers und schonmal danke!

    crash
    AMD Phenom II 940 BE @ 3,0 Ghz
    XFX HD 6870 (1024MB) @ Standard
    4x2GB DDR2-800 Kingston
    550W Be Quiet

  2. Anzeige
    Logge dich ein, um diese Anzeige nicht zu sehen.
  3. #2
    Lieutenant
    Dabei seit
    Okt 2004
    Beiträge
    608

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Eine Möglichkeit wäre:
    - Nehme dir eine Priority Queue (z.B. realisiert durch einen Heap)
    - Verwende den Timestamp, wann die Methode ausgeführt werden soll, als Key. Damit befindet sich die Methode, die als erstes aufgerufen werden soll immer an der Wurzel des Heaps.
    - Prüfe in regelmäßigen Abständen (z.B. 6 mal am Tag), ob der Timestamp der Wurzel erreicht wurde -> aufrufen und aus Heap entfernen

  4. #3
    Commander
    Dabei seit
    Mär 2008
    Beiträge
    2.196

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Entweder dieses oder aber jenes.

  5. #4
    Lt. Junior Grade
    Dabei seit
    Sep 2010
    Beiträge
    431

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Muss das Programm denn die ganze Zeit laufen? Oder kann es auch einfach zu den gewünschten Zeiten gestartet werden, die Methode ausführen und sich dann wieder beenden?
    Dann könntest du nämlich Cron benutzen, oder was ähnliches je nach Betriebssystem.

  6. #5
    Cadet 3rd Year
    Dabei seit
    Mär 2010
    Beiträge
    51

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Wie schon von Tumbleweed verlinkt, ein klarer Fall von http://quartz-scheduler.org/

  7. #6
    Cadet 4th Year
    Ersteller dieses Themas

    Dabei seit
    Jun 2010
    Beiträge
    127

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    @sacridex
    das programm muss die ganze zeit laufen, da es nebenbei noch andere aufgaben erledigt.

    @kinglouy
    bei deiner lösung stehe ich ja wieder vor dem problem das ich zu bestimmter zeit abfragen muss ob der timestamp erreicht ist. Und andauernd per while schleife abfragen will ich nicht. Oder habe ich dich falsch verstanden?

    @Tumbleweed
    quartz hatte ich schonmal im blick, wollte aber gucken ob es auch mit java built in geht
    AMD Phenom II 940 BE @ 3,0 Ghz
    XFX HD 6870 (1024MB) @ Standard
    4x2GB DDR2-800 Kingston
    550W Be Quiet

  8. #7
    Lieutenant
    Dabei seit
    Okt 2004
    Beiträge
    608

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Zitat Zitat von Crashdowns Beitrag anzeigen
    @kinglouy
    bei deiner lösung stehe ich ja wieder vor dem problem das ich zu bestimmter zeit abfragen muss ob der timestamp erreicht ist. Und andauernd per while schleife abfragen will ich nicht. Oder habe ich dich falsch verstanden?
    Hätte ich mit Thread.sleep() gemacht, wenn bekannt ist, wann in etwa abgefragt werden muss. Es müsste ja nur die Differenz zwischen der aktuellen Zeit und dem Zeitpunkt, wann aufgerufen werden soll, gebildet werden. Schon weißt du, wie lange der Thread warten muss.
    Dass Polling nie optimal ist, ist mir schon klar. War nur eine einfache Lösung, die mir spontan eingefallen ist.

  9. #8
    Ensign
    Dabei seit
    Jan 2006
    Beiträge
    245

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Hi!

    Kurzes Beispiel, wie man es lösen könnte.
    Kurz gefasst haben wir zwei Threads. Einer davon ist nur dafür zuständig, den anderenThread jede Sekunde aufzuwecken, damit der überprüfen kann, ob's was zum Arbeiten gibt. Dafür überprüft er für eine beliebige Anzahl von Tageszeiten, ob eine davon schon überschritten ist und fängt an zu arbeiten.

    Liebe Grüße!

    Example.java

    Code:
    public class Example {
    
        // ===================================================================
        // {[> Initializers and Constructors
        // =================================
        public Example() {
            final Object threadMonitor = new Object();
            new WorkerThread(threadMonitor);
            new PollerThread(threadMonitor);
        }
    
    
        // ===================================================================
        // {[> Public Static Methods
        // =========================
        public static void main(String[] args) {
            new Example();
        }
    }
    TimeOfDay.java
    Code:
    public class TimeOfDay {
    
        // ===================================================================
        // {[> Attributes
        // ==============
        private final int h, m, s;
    
    
    
        // ===================================================================
        // {[> Initializers and Constructors
        // =================================
        public TimeOfDay(int hour, int minute, int second) {
            h = hour;
            m = minute;
            s = second;
        }
    
    
    
        // ===================================================================
        // {[> Public Methods
        // ==================
        public final boolean isAfter(GregorianCalendar gc) {
            int hour = gc.get(Calendar.HOUR_OF_DAY);
            int minute = gc.get(Calendar.MINUTE);
            int second = gc.get(Calendar.SECOND);
            
            if (hour > h) {
                return true;
            } else if (hour == h) {
                if (minute > m) {
                    return true;
                } else if (minute == m) {
                    if (second > s) {
                        return true;
                    }
                }
            }
    
            return false;
        }
    }
    PollerThread.java
    Code:
    public class PollerThread extends Thread {
    
        // ===================================================================
        // {[> Attributes
        // ==============
        private final Object threadMonitor;
    
    
    
        // ===================================================================
        // {[> Initializers and Constructors
        // =================================
        public PollerThread(Object threadMonitor) {
            this.threadMonitor = threadMonitor;
            start();
        }
    
    
    
        // ===================================================================
        // {[> Public Methods
        // ==================
        public void run() {
            while (true) {
                try {
                    sleep(1000);
                } catch (InterruptedException e) {}
    
                synchronized (threadMonitor) {
                    threadMonitor.notifyAll();
                }
            }
        }
    }
    WorkerThread.java
    Code:
    public class WorkerThread extends Thread {
    
        // ===================================================================
        // {[> Attributes
        // ==============
        private final Object threadMonitor;
        private final TimeOfDay[] times;
    
        private int step = 0;
    
    
    
        // ===================================================================
        // {[> Initializers and Constructors
        // =================================
        public WorkerThread(Object threadMonitor) {
            this.threadMonitor = threadMonitor;
    
            this.times = new TimeOfDay[6];
            this.times[0] = new TimeOfDay(0, 0, 0);
            this.times[1] = new TimeOfDay(4, 0, 0);
            this.times[2] = new TimeOfDay(8, 0, 0);
            this.times[3] = new TimeOfDay(12, 0, 0);
            this.times[4] = new TimeOfDay(16, 0, 0);
            this.times[5] = new TimeOfDay(20, 0, 0);
    
            start();
        }
    
    
    
        // ===================================================================
        // {[> Public Methods
        // ==================
        public void run() {
            GregorianCalendar gc;
    
            while (true) {
                synchronized (threadMonitor) {
                    try {
                        threadMonitor.wait();
                    } catch (InterruptedException e) {}
                }
    
                gc = new GregorianCalendar();
                if (times[step].isAfter(gc)) {
                    System.out.println("work: " + step);
                    step = (step + 1) % times.length;
                }
            }
        }
    }

  10. #9
    Commander
    Dabei seit
    Mär 2008
    Beiträge
    2.196

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Was spricht denn gegen ein simples
    Code:
    		ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    		// Berechnung der Zeitdifferenz
    		executor.scheduleAtFixedRate(new Runnable()
    		{
    			@Override
    			public void run()
    			{
    				// call method
    			}
    		}, initialDelay, period, TimeUnit.SECONDS);
    wobei initialDelay einfach die Differenz von Programmstart und erster Ausführung ist und die period dann 4h.
    Und wenn man mit Zeiten hantiert, ist Joda-Time empfehlenswert. Erspart viel Arbeit und ist gut lesbar.

  11. #10
    Cadet 4th Year
    Ersteller dieses Themas

    Dabei seit
    Jun 2010
    Beiträge
    127

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    @Tumbleweed
    Die Lösung wäre einfach und elegant, leider soll das Programm nicht 6mal am Tag im 4h Abstand gestartet werden, sondern nur zu 6 bestimmten Uhrzeiten (8:00, 9:00, 12:00, 16:00, 18:00, 21:00).
    @Killkrog
    Ist auch wieder eine Polling basierte Lösung, werde ich aber im Hinterkopf behalten falls sich aus den anderen Idee nichts ergbit. Da ich morgen eine Prüfung schreibe bin ich nocht nicht dazu gekommen alle Vorschläge auszutesten (nach einer oberflächlichen Betrachtung könnte Quartz das Problem ja ggf. lösen).

    Weitere Idee und Vorschläge sind stets Willkommen.
    Geändert von Crashdowns (06.08.2012 um 20:09 Uhr)
    AMD Phenom II 940 BE @ 3,0 Ghz
    XFX HD 6870 (1024MB) @ Standard
    4x2GB DDR2-800 Kingston
    550W Be Quiet

  12. #11
    Commander
    Dabei seit
    Mär 2008
    Beiträge
    2.196

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Sei doch mal kreativ!

    Code:
    	private static int index;
    	final static long[] executionTimeDifferences = new long[] { 60, 180, 240, 120, 180, 660 };
    	final static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    	
    	private static int determineFirstIndex() {
    		// find start index here
    		return 2;
    	}
    	
    	private static class RepetitiveTask implements Runnable
    	{
    		@Override
    		public void run() {
    			// call your method
    			
    			if (++index >= executionTimeDifferences.length) {
    				index = 0;
    			}
    			executor.schedule(new RepetitiveTask(), executionTimeDifferences[index], TimeUnit.MINUTES);
    		}
    	}
    	
    	public static void main(String[] args) {
    		executor.schedule(new RepetitiveTask(), executionTimeDifferences[determineFirstIndex()], TimeUnit.MINUTES);
    	}
    Erhebt keinen Anspruch auf Vollständigkeit und/oder Richtigkeit. Ein bisschen grübeln sollst du ja auch.
    Geändert von Tumbleweed (06.08.2012 um 22:16 Uhr)

  13. #12
    Ensign
    Dabei seit
    Jan 2006
    Beiträge
    245

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Ich glaube, um Polling wirst du nicht drum rum kommen. Ich schätze mal, auch wenn ich es nicht genau weiß, dass Quartz intern das selbe Prinzip benutzen muss. Außer es geht nativ auf die OS Events los...
    Lasse mich gerne eines besseren belehren!

    Ergänzung:
    Hmm, kaum denkt man ein wenig über seinen eigenen Post nach, kommt man auf neue Ideen
    Das hier wäre auch eine Möglichkeit ohne Polling...

    Code:
    public static final void sleepUntil(Calendar date) throws InterruptedException {
        Thread.sleep(Math.max(date.getTimeInMillis() - System.currentTimeMillis(), 0));
    }
    Geändert von Killkrog (06.08.2012 um 23:05 Uhr)

  14. #13
    Cadet 4th Year
    Ersteller dieses Themas

    Dabei seit
    Jun 2010
    Beiträge
    127

    [Java] AW: Methode zu bestimmter Uhrzeit starten

    Habe jetzt den letzten Vorschlag von Killkrog umgesetzt. War simple und einfach nachvollziehbar für nachfolgende Nutzer.
    Danke für die Hilfe Leute!
    AMD Phenom II 940 BE @ 3,0 Ghz
    XFX HD 6870 (1024MB) @ Standard
    4x2GB DDR2-800 Kingston
    550W Be Quiet

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •