Thread pausieren, lange while-Schleife

J

JanStre

Mitglied
Hallo,

ich habe einen Thread programmiert, der ohne die deprecated-methoden auskommt. Bisher konnte ich es so veranlassen, dass der Thread gestartet, pausiert und beendet werden kann.
Ich möchte die Funktionalität dahingehend erweitern, dass nach dem Pausieren der Thread dort weitermacht, wo er aufgehört hat. Das ist u.a. notwendig, wenn in der while-Schleife eine lange Prozedur abgearbeitet wird. Bisher wird das Pausieren damit beendet, dass die while-Schleife wieder oben beginnt und neu anfängt zu arbeiten.

Java:
public class BeendenThread1 {
  static TestThread1 testThread = new TestThread1();
  
  public static void main (String[] args) 
                     throws InterruptedException {
	
	testThread.start();
    Thread.sleep(5500);
    
    testThread.interrupt();
    Thread.sleep(2000);
    TestThread1.pausing = false;
    
    
    Thread.sleep(5000);
    testThread.interruptAndStop();
  }
}

Java:
public class TestThread1 implements Runnable{

  Thread thread = null;
  public static boolean pausing;
  
  public synchronized void start(){
    if (thread == null){
      thread = new Thread(this);
      thread.start();
    }
  }
  
  public synchronized void stop(){
	  if (thread != null)
	    thread = null;
	}
  
  public void interruptAndStop(){
	  interrupt();
	  pausing = false;
	  stop();
  }
  
  public synchronized void interrupt(){
	  pausing = true;
	    if (thread != null)                
	      thread.interrupt();              
	  }
  
  public void sleep(){
	  try {
		  synchronized(this){
			  Thread.sleep(1000);
		  }
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
  }
  
  public void pause() throws InterruptedException{
	  pausing = true;
	  while(pausing){
		  synchronized(this){
			  Thread.sleep(1000);
		  }
		  System.out.println("Thread pausiert weiter");
	  }
  }
  
  public void run(){
    long startZeit = System.currentTimeMillis();
    int i = 1;
    System.out.println("Thread gestartet");
    while (thread != null){
    	try{
    		Thread.sleep(1000);
    		System.out.println(i++);
    	}
    	catch(InterruptedException e){
    		System.out.println("Thread pausiert");
    		try {
    			if(pausing){
    				pause();	
    			}
    			else {break;}
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
    	}
    }
    long dauer = System.currentTimeMillis()-startZeit;
    System.out.println("Thread gestoppt, Lebensdauer: "
                       + dauer);
  }
  
}

Würde der Prozess innerhalb der while-Schleife beispielsweise 10 Sekunden dauern und bei 5 Sekunden wird Pause ausgelöst:
Bisher wird die Pause beendet und die while-Schleife fängt oben bei 0 Sekunden wieder an.
Ziel ist es, bei 5 Sekunden die Arbeit wiederaufzunehmen.
 
S

SlaterB

Gast
ich kann den Code gerade nicht ausprobieren, auf Sicht ist aber nicht nachzuvollziehen, warum i wieder auf 0 gesetzt wird
oder was immmer du mit 'while-Schleife fängt oben bei 0 Sekunden wieder an' meinst (leider ohne Erklärung)

in jedem Fall gilt allgemein, dass du immer und überall die volle Kontrolle über alles hast,
programmiere es so wie du möchtest,
eine Schleife fängt wieder von vorne an, wenn etwa nach einem try/ catch nach 'davor' gesprungen wird, eigentlich nur innerhalb einer zweiten höheren Schleife möglich,
willst du das nicht, dann das try/catch enger setzen oder was immer aktuell los ist
 
J

JanStre

Mitglied
Ok, war vielleicht kein passendes Beispiel; hier etwas besseres:

Java:
public void run(){
    long startZeit = System.currentTimeMillis();
    System.out.println("Thread gestartet");
    while (thread != null){
    	try{
    		Thread.sleep(1000);
    		System.out.println("Ausführung1");
    		Thread.sleep(1000);
    		System.out.println("Ausführung2");
    		Thread.sleep(1000);
    		System.out.println("Ausführung3");
    		Thread.sleep(1000);
    		System.out.println("Ausführung4");
    		Thread.sleep(1000);
    		System.out.println("Ausführung5");
    		Thread.sleep(1000);
    		System.out.println("Ausführung6");
    	}
    	catch(InterruptedException e){
    		System.out.println("Thread pausiert");
    		try {
    			if(pausing){
    				pause();	
    			}
    			else {break;}
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
    	}
    }
    long dauer = System.currentTimeMillis()-startZeit;
    System.out.println("Thread gestoppt, Lebensdauer: "
                       + dauer);
  }

das sollte folgende Ausgabe ergeben:
Thread gestartet
Ausführung1
Ausführung2
Ausführung3
Ausführung4
Thread pausiert
Thread pausiert weiter
Thread pausiert weiter
Ausführung1
Ausführung2
Ausführung3
Ausführung4
Thread pausiert
Thread gestoppt, Lebensdauer: 12000


Was ich möchte ist aber, das nach der Pause mit Ausführung5 weiter gemacht wird, bzw. wenn man ganz genau ist, wenn ausführung4 noch nicht vollständig abgearbeitet ist, dort weitermacht.
Mir ist schon klar, dass ich das irgendwie kontrollieren kann, aber bisher hab ich es noch nicht rausgefunden ;)
 
J

JanStre

Mitglied
Ja den Ansatz habe ich auch schon verfolgt, aber leider konnte ich das bisher noch nicht implementieren.
Wie muss ich das wait() und notify() denn für diesen Thread anwenden, hab mit den Methoden bisher keine Erfahrung.
 
S

SlaterB

Gast
wait/ notify ist vielleicht schöner, hilft aber nicht unbedingt bei genau deinem Punkt,

es gilt wie ich es gesagt hatte, das try/ catch nicht über die gesamte Befehlsmenge, sondern zwischen jeden Befehl einzeln,

das klingt zunächst aufwendig, aber es gibt ja wie immer die Möglichkeit zu Untermethoden,
schreibe also
Java:
            System.out.println("Ausführung1");
            sleep1000MaybePause();
            System.out.println("Ausführung2");
            sleep1000MaybePause();
            System.out.println("Ausführung3");
            sleep1000MaybePause();
            System.out.println("Ausführung4");
            sleep1000MaybePause();
            System.out.println("Ausführung5");
            sleep1000MaybePause();
            System.out.println("Ausführung6");
mit einer neuen Methode sleep1000MaybePause(); die zunächst nur 1000 ms wartet, per try/catch aber Pause feststellt und dann länger wartet usw., ganz wie im derzeitigen try/catch,
wenn das dann fertig ist, gehts an der richtigen Stelle weiter

das try/catch in run() kann dann wahrscheinlich wegfallen

------

allgemein ist es nicht schön, nach jedem Befehl so ein Sonderkommando zu schreiben,
aber ganz nach jedem muss ja nicht sein, und wenn man wiederholt Untermethoden aufruft, kann man das optimierend zusammenlegen, etwa
Java:
printThanSleep1000MaybePause("Ausführung1");
printThanSleep1000MaybePause("Ausführung2");
printThanSleep1000MaybePause("Ausführung3");
printThanSleep1000MaybePause("Ausführung4");
das mit dem Namen ist natürlich nur zur Erklärung, eher hat man sicher Namen die sich auf die Aufgabe beziehen und dass dann am Ende der Untermethode gewartet wird, muss man sich eben merken

-----

vielleicht will man die Logik-Methoden aber sauber halten, die Thread-Pausen-Steuerung soll eher separat laufen,
noch ein Denkansatz:

es gibt eine Methode
runAndSleepMaybePause(Runnable r);
die das Runnable ausführt (einfach nur ein Objekt mit run-Methode, kein eigener Thread), dann wartet und mit try/ catch vielleicht pausiert,

von der Haupt-Kontrolle des Threas werden Runnable-Objekte erstellt, in denen die Methodenaufrufe stehen und dann runAndSleepMaybePause() aufgerufen,
Runnable-Objekte etwa als anonyme Klassen zu erstellen kann sehr viel unschönen Code erzeugen, mit Schleifen geht es einigermaßen, was in deinem Beispiel denkbar wäre:
Java:
List<Runnable> list = ..
for (i ..) {
  final int finalI = i;
  list.add(new Runnable() {
    public void run() {
      System.out.println("i: "+i);
    }
  });
}

for (Runnable r : list) {
   runAndSleepMaybePause(r);
}
erst Runnable-Objekte erstellen, die noch nix tun, aber die Kommandos enthalten,
dann diese nacheinander an runAndSleepMaybePause() schicken, dort werden sie ausgeführt (run() aufrufen), geschlafen + evtl. pausiert


---------

edit:

einen Abbruch des Threads aus den Untermethoden heraus zur main-Schleife geht mit den mehrfachen einzelnen Befehlen printThanSleep1000MaybePause() per boolean-Rückgabewert und lauter ifs relativ schlecht, viel unnötiger Code, da bietet sich eine RuntimeException an, die dann doch wieder mit try/catch ganz außen gefangen wird,

bei den Runnable in einer Liste, die nur an einer einzigen Code-Stelle ausgeführt werden:
Java:
for (Runnable r : list) {
   runAndSleepMaybePause(r);
}
wäre dagegen möglich den Thread-Abbruch per Rückgabewert false und einem if zu steuern
 
Zuletzt bearbeitet von einem Moderator:
J

JanStre

Mitglied
Ich hab mir noch überlegt, das ganze einfach über einen Status der Maschine zu steuern.

Nach jeder "Ausführung" wird der Status inkrementiert, am Ende der while-Schleife wieder resettet. Wenn jetzt innerhalb der while-Schleife ein Interrupt kommt, merkt man sich einfach den Status und nach dem try-catch fängt die while-Schleife praktisch oben an, fängt aber mit der Methode dort an, deren Ausführung noch nicht komplett beendet wurde:
So wie es jetzt aussieht, könnte man das ganze noch in eine sehr einfaches switch-case-konstrukt umwandeln, das jedesmal in der while-schleife abgelaufen wird.

Java:
    while (thread != null){
    	try{
    		if(status == 0){
    			Thread.sleep(1000);
    			System.out.println("Ausführung1");
    			status++;
    		}
    		if(status == 1){
    			Thread.sleep(1000);
    			System.out.println("Ausführung2");
    			status++;
    		}
    		if(status == 2){
    			Thread.sleep(1000);
    			System.out.println("Ausführung3");
    			status++;
    		}
    		if(status == 3){
    			Thread.sleep(1000);
    			System.out.println("Ausführung4");
    			status++;
    		}
    		if(status == 4){
    			Thread.sleep(1000);
    			System.out.println("Ausführung1");
    			status++;
    		}
    	}
    	catch(InterruptedException e){
    		System.out.println("Thread pausiert");
    		try {
    			if(pausing){
    				pause();	
    			}
    			else {break;}
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
    	}
    	status = 0;
    }
 
S

SlaterB

Gast
durchaus denkbar, könnte man meiner Runnable-Version zuordnen, hier in dem einfachen Fall mit nur einer Art Aktion ist diese direkt angegeben,

auch wenn es sicher nur ein Beispiel ist, lohnt es sich immer die Optimierungen zu betrachten:
> Thread.sleep(1000);
+
> status++;
stehen in jedem if, die können aus den ifs raus und nur einmal am Anfang bzw. Ende der Schleife stehen,

die System.out.println-Kommandos hängen direkt vom status ab, da muss kein if oder switch her,
ein direkter Befehl berechnet das richtig:
> System.out.println("Ausführung"+(status+1));
 
J

JanStre

Mitglied
ja die konzepte sind klar, waren ja auch nur anschauliches material um die ausführungszeit zu simulieren, dahinter stehen methoden, die durchaus mal 5-10 Sekunden dauern können (nicht wegen rechenzeit, sondern auch wegen wartezeiten ihrereseits)

ich schließ den thread mal, ich hab mit dem status-konstrukt meine lösung gefunden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Aruetiise Swing JOptionPane ohne denn Thread zu pausieren Allgemeine Java-Themen 1
Y Thread pausieren Allgemeine Java-Themen 6
M Thread pausieren Allgemeine Java-Themen 8
W Server-Thread schreibt nicht alle Dateien Allgemeine Java-Themen 6
NicoDeluxe Logfile pro User / Thread Allgemeine Java-Themen 7
NicoDeluxe Thread / Service abbrechen Allgemeine Java-Themen 3
Thallius Ist meine static Helper Class Thread save? Allgemeine Java-Themen 9
P Swing Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: npoints > xpoints.length || npoints > ypoints.length Allgemeine Java-Themen 5
B Thread.sleep() in EJB Container wie lösen? Allgemeine Java-Themen 11
S Ist das Neuzuweisen von Feldern atomic und damit Thread-Safe? Allgemeine Java-Themen 2
S Exception in thread "main" java.lang.NullPointerException at FamilienApp.main(FamilienApp.java:15) Allgemeine Java-Themen 1
J Einen Thread in einer Schleife Allgemeine Java-Themen 2
E HILFE !! Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils Allgemeine Java-Themen 4
Flynn Thread-Problem... Allgemeine Java-Themen 2
G Thread-Programmierung Allgemeine Java-Themen 5
S Datei wird nicht gefunden Thread.currentThread().getContextClassLoader().getResourceAsStream() Allgemeine Java-Themen 1
G Beendet sich der Thread selbst?! Allgemeine Java-Themen 3
mrbig2017 Sleep wird ignoriert und der Thread wartet nicht Allgemeine Java-Themen 1
S Thread beenden Allgemeine Java-Themen 9
M Array aus Thread Objekten erstellen Allgemeine Java-Themen 2
M Nanosekunden-Pause innerhalb einen Thread-Loops Allgemeine Java-Themen 3
E Thread Exception Allgemeine Java-Themen 6
javaerd Binomialkoeffizient ausrechnen, Exception in thread "main" java.lang.StackOverflowError Allgemeine Java-Themen 6
T Merkwürdiges Thread-Verhalten Allgemeine Java-Themen 6
K Thread Problem Allgemeine Java-Themen 6
W Thread sleep 30 sekunden - wenn keine Antwort bis dahin neu senden Allgemeine Java-Themen 2
H Thread bleibt stehen bei jar in jar Allgemeine Java-Themen 1
J Threads HTTP Request (Thread) dauert lange - in Android Allgemeine Java-Themen 3
F CPU Last eines Thread ausfindig machen Allgemeine Java-Themen 0
V Compiler-Fehler Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 125, Size: 125 Allgemeine Java-Themen 11
Tausendsassa Threads Einen Thread sich selbst schließen lassen Allgemeine Java-Themen 17
P Threads BufferedImage, Thread Concurrency Allgemeine Java-Themen 1
M Klasse in separaten Thread ausführen.Wie genau? Allgemeine Java-Themen 2
llabusch Thread blockiert Dialog Allgemeine Java-Themen 1
J Thread wait() Allgemeine Java-Themen 2
V Thread.sleep und InterruptedException? Allgemeine Java-Themen 1
G Thread nicht von GC zerstört Allgemeine Java-Themen 6
J Wie erschaffe ich einen sicheren Datenaustausch zwischen Thread und Nicht-Threads Allgemeine Java-Themen 8
Sogomn Thread blocken bis Taste gedrückt Allgemeine Java-Themen 5
T Starten vom Thread Allgemeine Java-Themen 3
T Wait/Notify() bei Thread Allgemeine Java-Themen 6
J Exception in thread "main" java.lang.NoClassDefFoundError Allgemeine Java-Themen 4
M Exception in thread "AWT-EventQueue-0" Allgemeine Java-Themen 6
Q Thread wacht nicht auf Allgemeine Java-Themen 7
T Fragen zum Thread-Thema Allgemeine Java-Themen 4
T Threads Input/Output im Thread - Datei ohne Inhalt Allgemeine Java-Themen 1
T Fragen zum Thread-Thema Allgemeine Java-Themen 9
C Threads Variablen in einem Thread Aktualisieren Allgemeine Java-Themen 17
U Thread beenden Allgemeine Java-Themen 3
W Threads Mit Thread und Runtime externe Programme öffnen Allgemeine Java-Themen 0
N Thread interrupt Status debuggen Allgemeine Java-Themen 6
A Thread: Code paralell ausführen in mehreren Instanzen Allgemeine Java-Themen 1
E Threads linkedlist/multi-thread problem Allgemeine Java-Themen 3
B Erkennen, wann Prozess beendet ist, dann Thread beenden. Allgemeine Java-Themen 6
A Thread Fehler absichtlich provozieren Allgemeine Java-Themen 3
B Threads Java Thread kommunizieren Allgemeine Java-Themen 12
N Thread Sicherheit im komplexen Datenmodell Allgemeine Java-Themen 7
K Thread richtig benutzen Allgemeine Java-Themen 3
K Exception in thread "AWT-EventQueue-1" Allgemeine Java-Themen 2
vandread Problem bei kleiner Thread-Übung Allgemeine Java-Themen 2
G Thread erzeugt nicht plausible NullPointerException Allgemeine Java-Themen 7
H Netbeans Warning bei Thread.sleep in Schleife Allgemeine Java-Themen 4
P [Thread] Scheint nicht Sequenziell zu Arbeiten Allgemeine Java-Themen 9
A eine test thread.join() frage Allgemeine Java-Themen 2
tuttle64 Verständnisprobleme mit Thread Locks Allgemeine Java-Themen 4
G Threads Thread bei Datenabfrage Allgemeine Java-Themen 3
S Thread anhalten per Button ? Allgemeine Java-Themen 3
E Thread Programmierung Allgemeine Java-Themen 2
S Threads ServerSocket-Thread soll schlafen, bis er gebraucht wird Allgemeine Java-Themen 2
V Thread schneller stoppen Allgemeine Java-Themen 2
V anstatt thread.join() einfach while schleife? Allgemeine Java-Themen 8
B Mausbewegung im Thread erkennen (hoch/runter) Allgemeine Java-Themen 6
G Linux/C++/Pthreads auf JVM zugreifen, thread safe? Allgemeine Java-Themen 10
K Threads Probleme mit Thread Allgemeine Java-Themen 13
K Threads Thread überprüfen Allgemeine Java-Themen 3
Z Threads Thread für einen Client Allgemeine Java-Themen 9
M Thread JavaFish Allgemeine Java-Themen 10
G Thread.sleep Allgemeine Java-Themen 12
M Threads Viele Aufrufe aus Thread, komisches Verhalten Allgemeine Java-Themen 8
B Threads Main Thread warten auf abgebrochen Task warten lassen Allgemeine Java-Themen 25
K Timer Thread Allgemeine Java-Themen 8
M Methoden Static Methoden und Thread??? Allgemeine Java-Themen 4
N java.lang.IllegalMonitorStateException: object not locked by thread before notify() Allgemeine Java-Themen 2
C Mehothode in anderenm Thread aufrufen Allgemeine Java-Themen 10
R Thread läuft nicht?! Allgemeine Java-Themen 7
R ThreadPool - vorhandene thread liste überprüfen bzw. aufräumen Allgemeine Java-Themen 3
J Anderem Thread Variable mitgeben Allgemeine Java-Themen 2
C Argument an einen Thread übergeben Allgemeine Java-Themen 4
S java.util.ConcurrentModificationException - aber nur ein Thread Allgemeine Java-Themen 3
G JUnit Test Methoden in anderen Thread verlagern Allgemeine Java-Themen 4
P Java Probleme - java.lang.Thread.run(Unkown Source) Allgemeine Java-Themen 10
L Im Thread auf Eingaben warten Allgemeine Java-Themen 3
P aus Thread auf Form zugreifen Allgemeine Java-Themen 9
C Threads Thread blockieren Allgemeine Java-Themen 4
K Threads Thread für Sleep Allgemeine Java-Themen 6
H Threads Thread stirbt aber Objekte in ihm leben weiter?! Allgemeine Java-Themen 9
K Threads Thread aktualisiert Progressbar nicht Allgemeine Java-Themen 4
D Methoden Thread Schleife Status Allgemeine Java-Themen 7
T Thread Warteschlange Allgemeine Java-Themen 21
D Thread-Array (richtig) überwachen Allgemeine Java-Themen 3

Ähnliche Java Themen

Anzeige

Neue Themen


Oben