Wie kann ich einen Timer pausieren ?

andy72

Erfahrenes Mitglied
Habe ein Problem:

eine while-schleife läuft als thread, in dem ein Client-Socket eine Verbindung aufrecht erhält. Ein Java-Timer mit einem TimerTask sendet über diesen alle 60 Sekunden einen Ping an einen Server, da dieser sonst die Verbindung abbricht (wäre nicht sogut, da der Client-Socket ein Messenger ist). Wie kann ich nun bei kritischen Daten, die unverzüglich gesendet werden müssen, den Task anhalten und darauf neu starten ? Der Timer läuft Java-Intern selbst als Thread - ein Timer.wait() geht nicht, da ich den Timer-Thread nicht verwalten darf (Exception wird dann ausgelöst). Ein Timer.cancel() geht auch nicht, da innerhalb der while-schleife eine weitere Exception ausgelöst wird, wo es dann heisst, der Task sei längst beendet.

Bin für jede Idee dankbar, anbei noch der Code dazu:

Code:
public MyTimerTask extends TimerTask {
  public void run() {
    out.write(PING_DATA);
  }
}

Timer t = new Timer();
t.schedule(new MyTimerTask(), 5000, 60000);
String buffer = null;

boolean stop = true;
while(stop) {
  if( in.readLine() != null ) {
    out.write(critical_data); // Sendet zeitweise nicht, da der TimerTask gerade sendet
  }
}
 
so, ich wollte kein neues Thread aufmachen.
Ich habe fast dasselbe Problem.

Habe mehrere TimerTasks laufen. Nun möchte ich eins anhalten und evtl. später wieder starten.
Geht das?
 
das ist nun alles andere als eine gute Lösung, aber Thread.sleep() sollte gehen, du musst eben die Exception mit try-catch direkt in dem Block abfangen
 
das ist nun alles andere als eine gute Lösung, aber Thread.sleep() sollte gehen, du musst eben die Exception mit try-catch direkt in dem Block abfangen

Thread.sleep() geht da nicht.
Das sind TimerTasks und keine Threads, ich meine damit die Klassen.

Ich dachte, ich hätte das Problem gelöst:
Auf Wunsch des Benutzers mache ich
this.cancel()
Damit läuft der task nicht mehr. Alle relevante Information speichere ich in einer XML-Datei, z.B. Anzahl Runden, die gelaufen wurden.
Nun möchte ich diesen task wieder starten.
Der Aufruf in einer anderen Klasse, die das Timer-Objekt hat:
timer.schedule(myTask, 100, 100);
wirft folgende Fehlermeldung:
Code:
java.lang.IllegalStateException: Task already scheduled or cancelled
	java.util.Timer.sched(Timer.java:358)
	java.util.Timer.schedule(Timer.java:222)

Nun weiß ich nicht weiter.
:confused:
 
Hallo,

da der java.util.Timer die TimerTasks in einem Thread ausführt blockert ein Thread.sleep(...) in einem Task auch den ganzen Timer.

Ich würd das so ähnlich machen:
Java:
/**
 * 
 */
package de.tutorials;

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

/**
 * @author Tom
 * 
 */
public class ShedulerWithPauseSupport {

    /**
     * @param args
     */
    public static void main(String[] args) {

        final Task task0 = new Task("Task0");
        final Task task1 = new Task("Task1");

        ScheduledExecutorService scheduledExecutorService = Executors
                .newScheduledThreadPool(10);
        scheduledExecutorService.schedule(task0, 0, TimeUnit.SECONDS);
        scheduledExecutorService.schedule(task1, 0, TimeUnit.SECONDS);
        scheduledExecutorService.schedule(new Task("SandMan") {
            @Override
            public void run() {
                System.out.println(this.name + "about to task0 to bed");
                task0.shouldSleepFor30Seconds = true;
            }
        }, 20, TimeUnit.SECONDS);
    }

    static class Task implements Runnable {
        String name;

        public Task(String name) {
            this.name = name;
        }

        boolean shouldSleepFor30Seconds;

        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.printf(
                        "%s is executed in the context of thread: %s\n",
                        this.name, Thread.currentThread().getName());
                if (shouldSleepFor30Seconds) {
                    try {
                        System.out.println("sleeping: " + this.name);
                        TimeUnit.SECONDS.sleep(30);
                    } catch (InterruptedException e) {
                        // ignore
                    } finally {
                        shouldSleepFor30Seconds = false;
                    }
                }
            }
        }
    }
}

Gruß Tom
 
servus,

seh ich das also richtig, dass es keine möglichkeit gibt einen timer für unbestimmte zeit anzuhalten und ihn danach einfach wieder weiterlaufen zu lassen? (pause modus...)

einen thread kann man soweit ich die API verstehe zwar mit suspend anhalten.. allerdings werden diese methoden als hochgrading unsicher eingestuft...

was wäre denn sozusagen die feine englische art um eine z.b. stoppuhr als applet zu realisieren?
(nur auf das model bezogen natürlich...)

greeez

benny
 
Ich hab ein ähnliches Problem folgendermaßen gelößt (ging auch um so eine Art Stoppuhr):

Ich hab eine Klasse von Runnable abgeleitet und ihr nen flag namens run sowie nen int-Wert sec verpasst.

meine run-Methode sah dann folgendermaßen aus:

Java:
public void run() {
	while (true) {
		while (this.run) {
			this.sec++;
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}		
}

Ich hoffe, das hilft dir weiter.

Gruss, Manuel
 
Zurück