Dauerschleife unterbrechen mit sleep()

Status
Nicht offen für weitere Antworten.

brezn

Mitglied
Hallo Leute,

ich habe eine dauerschleife, die bestimmte aufgaben macht, bis irgendwann eine schaltervariable auf false gesetzt wird. sie sieht folgendermaßen aus:

Java:
while(an){
			... //Code der ausgeführt wird
			try{   
				Thread.sleep(schlagzeit); 
            }
            catch (Exception ex) {}

}

Die Variable an ist vom Typ boolean. Bekannterweiße gibt es ja einen stack overflow bei Dauerschleifen, also dachte ich mir, dass ich das ganze mit Thread.sleep() umgehen kann. Allerdings hängt sich auch hier das Programm auf. ist sleep() überhaupt die Lösung und wenn ja, was habe ich falsch gemacht?
wenn nein, welche anderen lösungen gibt es dann?
 
B

bygones

Gast
ein stackoverflow kommt nicht bei einer "endlos" bzw "dauerschleife" sondern "an application recurses too deeply"...

while(true) mit sleep ist immer zu ueberlegen (zb gegen notify und wait auszutauschen)
 
S

SlaterB

Gast
> Bekannterweiße gibt es ja einen stack overflow bei Dauerschleifen

nein

> dass ich das ganze mit Thread.sleep() umgehen kann

nein, wobei dir andere Dinge vielleicht helfen,
Thread.sleep() ermöglicht, weniger als 10 Milliarden Schleifendurchläufe pro Sekunde zu haben und 100% CPU-Belastung, auch nicht schlecht

> Allerdings hängt sich auch hier das Programm auf.

aus dem Code nicht zu erkennen, Thread.sleep() wird nicht alleine schuld sein

> ist sleep() überhaupt die Lösung

ohne genaue Problemstellung kaum zu beurteilen

> wenn ja, was habe ich falsch gemacht?

zumindest zuwenig erklärt/ kein vollständiger Code
 

The_S

Top Contributor
Bekannterweiße gibt es ja einen stack overflow bei Dauerschleifen

Ist mir eigentlich nicht bekannt.

Allerdings hängt sich auch hier das Programm auf.

Das Programm wartet bei jedem Durchlauf
Code:
schlagzeit
Millisekunden

ist sleep() überhaupt die Lösung und wenn ja, was habe ich falsch gemacht?

Kommt drauf an, was du eigentlich machen willst und wo das Problem liegt :p
 
B

bygones

Gast
manno man immer diese arbeitslosen Informatiker hier die alle zur selben Zeit das selbe antworten :D
 
S

Spacerat

Gast
"Thread.sleep()" ist weder für den Stack-Overflow verantwortlich, noch kann dieser dadurch verhindert werden.
Innerhalb von "while(an)" muß sichergestellt sein, das "an" irgendwann "false" wird, auch bzw. vorallem bei rekursivem Aufruf. "an = false;" gehört deswegen noch unbedingt in den "catch"-Block von "Thread.sleep()". Falls "an" eine Instanzvariable ist, kann "an" auch von ausserhalb beeinflusst werden, z.B. mit "setAn(false);".
 

brezn

Mitglied
oh okay, ich dachte, meine erklärungen reichen aus, aber da hab ich mich wohl getäuscht ^^

also gut. sorry, ich meinte nicht stack overflow, sondern cpu auslastung. sprich, man sollte der cpu doch mit Thread.yield() luft zum atmen geben, oder? das ist doch der sinn von dieser yield methode oder täusch ich mich da?

so, also mit Thread.yield() funktioniert es auch nicht. darum erkläre ich kurz mein programm. ich bastel grade an einem metronom für musiker. da kann man ein tempo einstellen und taktart und das ganze dann ablaufen lassen. da gibt es eine methode, die heißt zaehlen, in der diese Dauerschleife ist, die so lange zählt, bis der Benutzer eben wieder auf Stop klickt.
Hier die Methode zaehlen:
Java:
public void zaehlen(){
		while(an){
			if(aktZahl>otakt) aktZahl=1;
			draw.ZahlZeichnen(aktZahl);
			aktZahl++;
			try{   
                Thread.sleep(schlagzeit);
				Thread.yield(); 
            }
            catch (Exception ex) {}

		}
	}
draw ist eine Referenz auf eine klasse, die für das Zeichnen der Zahlen zuständig ist. Ich zeichne quasi den aktuellen Schlag vom Takt auf die Benutzeroberfläche. Die Variable schlagzeit gibt quasi das Tempo an, das heißt, die Schleife soll je nach eingestelltem Tempo entsprechend warten.

So, ich hoffe, ihr könnt mir nun bissel besser helfen ^^
 
S

SlaterB

Gast
selbst eine leere Schleife läßt die CPU auf 100% laufen, wenn kein Sleep drin ist,
dann wird eben umso öfter die Schleifenvariable erhöht usw. bzw. gar nichts gemacht außer hin und her zu springen bei while (true)

-------

mit Thread.sleep() kann man das verlangsamen, korrekt,

es ist nun immer noch keine Frage/ kein Problem sichtbar,
dass sich 'irgendwas aufhängt' läßt keine qualifizierten Schlüsse zu

du hast noch nicht mal erwähnt, welchen Wert schlagzeit enthält
 
S

Spacerat

Gast
"Thread.sleep(schlagzeit)" reicht hier völlig aus, könnte aber auch durch "wait(schlagzeit)" ersetzt werden (ACHTUNG: Synchronisation nötig). "Thread.yield()" sorgt in der Regel auch für eine 100%ige Prozessorauslastung. Damit teilt der Thread dem System mit, das er in der nächsten Runde ausgelassen werden möchte. Was nach wie vor fehlt, ist der Zwang-Abbruch ("an = false") im Catch-Block bzw. innerhalb der "while"-Schleife.
 

brezn

Mitglied
okay, dann poste ich mal das, was hinter draw steckt. draw ist eine Klasse die von JPanel abgeleitet ist, ich zeichne quasi in dieses JPanel selber rein.
Hier ist das, was hinter der Methode ZahlZeichnen steckt:

Java:
public void ZahlZeichnen(int zahl){
		this.zahl=zahl;
		repaint(); //Aufruf der paintComponent() Methode
}
	
public void paintComponent(Graphics g) {
    super.paintComponent(g);
        
    switch(zahl){
      case 0: g.drawImage(blank, 21, 0, this);break;
      case 1: g.drawImage(one, 21, 0, this); break;
      case 2: g.drawImage(two, 21, 0, this); break;
      case 3: g.drawImage(three, 21, 0, this); break;
      case 4: g.drawImage(four, 21, 0, this); break;
      case 5: g.drawImage(five, 21, 0, this); break;
      case 6: g.drawImage(six, 21, 0, this); break;
      case 7: g.drawImage(seven, 21, 0, this); break;
      case 8: g.drawImage(eight, 21, 0, this); break;
      case 9: g.drawImage(nine, 21, 0, this); break;
    }  		 
}

edit: schlagzeit nimmt korrekte werte an! das habe ich mir schon ausgeben lassen. da braucht ihr euch keine sorgen zu machen. schlagzeit pendelt im bereich zwischen 0,1 und 3 sekunden.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
@ brezn
wahrscheinlich mein Post zwischendurch noch nicht gesehen, dennoch zur Wiederholung:
es ist immer noch kein Problem ersichtlich, egal was ZahlZeichnen alles macht

Methoden klein schreiben!

-------

Bei Java nicht! Hatte ich mal ausprobiert und die JVm macht einfach garnichts.
wird denn der Code dahinter ausgeführt oder macht das Programm an sich ne Endlos-Pause? ;)

man muss evtl. bisschen tricksen, also von gar nix wieder auf 'nur Schleifenvariable prüfen/ ändern' zurückgehen,
sonst gibts gar nen Compiler-Fehler (Unreachable Code)

Java:
public class Test
{
    public static void main(String[] args)
    {
        int a = 3;
        System.out.println("a");
        while (a > 2) {}
        System.out.println("b");
    }
}

edit:
oder doch mit while(true):
Java:
public class Test
{
    public static void main(String[] args)
        throws Exception
    {
        System.out.println("a");
        try
        {
            while (true) {}
        }
        catch (Exception e) {}
        System.out.println("b");
    }
}
was passiert da bei dir wenn nicht 100% CPU (auf einen Kern)?
 
Zuletzt bearbeitet von einem Moderator:

brezn

Mitglied
@SlaterB: also das problem ist dir noch nicht ganz so klar, meinst du?
also es ist so, wenn ich auf Start klicke, dann soll das Metronom anfangen zu zählen. bei mir zählt halt noch nichts und das Programm hängt sich anscheinend auf, weil man nichts mehr anderes anklicken kann und das ganze nur noch mit dem Task Manager beenden kann.

Ich habe an=false nun mal mit eingebaut, ändert aber nicht wirklich was. false wird auch nur von außerhalb gesetzt, also wenn ich auf den Button stopp klicke. von daher kann ich das nicht wirklich in die schleife einbauen.
Java:
public void zaehlen(){
		while(an){
			if(aktZahl>otakt) aktZahl=1;
			draw.zahlZeichnen(aktZahl);
			aktZahl++;
			try{   
				Thread.yield(); 
            }
            catch (Exception ex) {
            	an=false;
            }

		}
	}
 
S

Spacerat

Gast
Jetzt wird mir so einiges Klar. Kann es sein, das die "zaehlen()"-Methode gar nicht in einem eigenen Thread läuft? Wenn dem so ist, kannst du natürlich lannge darauf warten, das sich irgendwo anders noch was tut. Der Start-Button muß also einen neuen Thread starten, sonst wartet die gesamte Anwendung darauf, das die "while"-Schleife beendet wird.
 
S

SlaterB

Gast
wahrscheinlich unbewußt hast du nun in deinen Nebensätzen neue Informationen preisgegeben,
besser so als gar nicht,

es klingt so, als hättest du eine graphische Oberfläche, die nicht mehr reagiert, das bringt uns natürlich weiter,
solange ein ActionListener oder ähnliches ausgeführt wird, ist die GUI generell blockiert,

wenn du sekunden- oder minutenlange Tasks startest, dann gehören diese in separate Threads,
damit die GUI weiterarbeiten und auf andere Ereignisse reagieren kann

siehe
http://www.java-forum.org/java-faq-beitraege/7395-progressbars-algorithmen-und-multithreading.html

etwas einfacher
Java ist auch eine Insel – 15.33 AWT, Swing und die Threads
 

brezn

Mitglied
aha, okay, verstehe ^^
ich muss zugeben, ich kenne mich mit threads kein bisschen aus! ich hab nur mal gelesen, dass man eben aufpassen muss und der CPU noch luft zum atmen geben muss und das halt mit Yield oder Sleep ginge. Das da dann noch jede menge mehr dahinter steckt, wusste ich nicht.
dann les ich mich erstmal in diese Thread thematik ein und schrei dann nochmal, wenn ich wieder probleme habe ^^

vielen dank erstmal :p

edit: @ spacerat: die zaehlen Methode ist nicht in einem thread.
@SlaterB: ja, ich habe eine GUI. darum ja auch JPanel und "zeichen" die ganze zeit. der ActionListener ist eigentlich schon beendet, das hat damit nix mehr zu tun. denke ich jetzt mal. der actionlistener wird dann aktiviert, wenn ich auf Start klicke. dann ruft die GUI klasse die Metronom Klasse auf und darauf die starte()-methode, die wiederum ruft die zaehlen()-methode auf. also dürfte der actionlistener damit nix mehr zu tun haben, oder?
 
Zuletzt bearbeitet:

Noctarius

Top Contributor
was passiert da bei dir wenn nicht 100% CPU (auf einen Kern)?

Hmm stimmt 90-96% CPU Auslastung... Ich glaub ich hatte damals einfach nur eine leere Schleife definiert aber auch das geht grad nicht. Hm was hatte ich damals anders gemacht? *denk*

Ich hatte mich damals nämlich auch total gewundert, dass es eben nicht passierte.
 

brezn

Mitglied
so, ich hab jetzt mal in meinem buch über threads nach gelesen, aber wirklich viel stand da nicht drin.
ich habe eine Klasse Metronom, wo sich alles abspielt, also wo die schlagzeit ausgerechnet wird, wo hochgezählt wird etc... blöderweise funktioniert das immer noch nicht. ich hab alles so gemacht, wie es im buch stand.

Java:
public class Metronom extends Thread {
	Integer tempo, otakt, utakt;
	Zeichnen draw;
	Double zeit;
	boolean an=false;
	long schlagzeit;
	int aktZahl=1;
	String z;
	
	public Metronom(Integer tempo, Integer otakt, Integer utakt, Zeichnen draw){
		this.tempo=tempo;
		this.otakt=otakt;
		this.utakt=utakt;
		this.draw=draw;
	}
	
	public void start(){
		switch(utakt){
    		case 1: zeit = 60.0/tempo*4*1000;break;
    		case 2: zeit = 60.0/tempo*2*1000;break;
    		case 4: zeit = 60.0/tempo*1000;break;
    		case 8: zeit = 60.0/tempo/2*1000;break;
		}
		schlagzeit=zeit.longValue();  //Umwandlung von Double in Long
		System.out.println(schlagzeit);  //Zum Test ausgeben
		an=true;
		run();
	}
	
	public void run(){
		while(an){
			if(aktZahl>otakt) aktZahl=1;
			draw.zahlZeichnen(aktZahl);
			aktZahl++;
			try{   
				sleep(schlagzeit); 
            }
            catch (Exception ex) {
            	an=false;
            }
		}
	}
}
 
S

SlaterB

Gast
die Methode start() am besten nicht überschreiben und schon gar nicht run() aufrufen,
das kann so ja nicht in dem Buch stehen

was du an Initialisierung brauchst kommt entweder in den Konstruktor oder an den Anfang der run()-Methode

-------

statt von Thread zu erben implementiere lieber Runnable, dann kannst du gar nicht start() überschreiben,

Runnabe r = mein eigenens Runnable...;
new Thread(r).start();
 

brezn

Mitglied
ach was, jetzt funktionierts... habs so gemacht, wie du gesagt hast, allerdings immer noch mit extends Thread und nicht mit runnable.

es lag also daran, dass ich run() selber aufgerufen habe... darf ich das nicht? warum ned?

vielen dank für die hilfe.
 
S

SlaterB

Gast
run() ist eine Methode, wie sie auch a() oder b() heißen könnte, der Name alleine bewirkt noch nichts,
auch das Thread-Objekt ist zu großen Teilen ein normales Objekt ohne Sonderstatus

es bedarf schon einer Menge Hintergrund-Magie, damit da ein separater Thread abläuft,
und da lautet das Konstrukt eben:
start() aufrufen,
-> intern wird irgendwas gestartet was letztlich zu einem neuen Thread führt,
-> der dann run() aufruft

zu einem bestimmten Grad ähnlich einem ActionListener,
da ruft man die actionPerformed()-Methode ja auch nicht selber auf
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Methode endet in Dauerschleife Java Basics - Anfänger-Themen 10
C Frage für Programm mit Dauerschleife im Hintergrund Java Basics - Anfänger-Themen 11
W While-Loop unterbrechen Java Basics - Anfänger-Themen 4
H Ausgabe nach 20sek und eventuell unterbrechen Java Basics - Anfänger-Themen 2
E mit java-anwendung internet verbindung unterbrechen Java Basics - Anfänger-Themen 5
A Thread.sleep() unterbrechen? Java Basics - Anfänger-Themen 3
D Audioclip Unterbrechen Java Basics - Anfänger-Themen 3
G Netzwerk unterbrechen Java Basics - Anfänger-Themen 10
Dit_ Thread | Schleifenlose run-Methode unterbrechen. Java Basics - Anfänger-Themen 23
Y Mit F3 Programmablauf unterbrechen Java Basics - Anfänger-Themen 6
M Timer unterbrechen? Wo ist mein Thread? Java Basics - Anfänger-Themen 2
G Prozedur in einer anderen Prozedur unterbrechen Java Basics - Anfänger-Themen 5
T Durchlauf einer for-Schleife unterbrechen - wie ? Java Basics - Anfänger-Themen 11
J schleife unterbrechen JTextArea aktualisieren Java Basics - Anfänger-Themen 8
L unterbrechen von bufferedReader.read() Java Basics - Anfänger-Themen 4
berserkerdq2 Warum muss man manchmal in der RUnmethode sleep in eine schleife tun? Java Basics - Anfänger-Themen 9
F Thread.sleep() Java Basics - Anfänger-Themen 5
S Berechnung der sleep time ist falsch Java Basics - Anfänger-Themen 46
B Threads Thread sleep() Method einfache Frage Java Basics - Anfänger-Themen 8
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
S Thread.sleep mit JProgressBar Java Basics - Anfänger-Themen 1
A Problem mit Thread.sleep Java Basics - Anfänger-Themen 4
M Thread.sleep() Funktion Java Basics - Anfänger-Themen 1
I Thread.sleep (1000); Java Basics - Anfänger-Themen 1
Lord.Djerun (Netbeans) Bei TimeUnit.Seconds,Sleep() hängt sich das komplette Programm auf.. Java Basics - Anfänger-Themen 8
S Oberfläche aktualisiert nicht wegen sleep Java Basics - Anfänger-Themen 1
S sleep Java Basics - Anfänger-Themen 4
P Threads Thread.sleep() Java Basics - Anfänger-Themen 7
C Wie funktioniert sleep Java Basics - Anfänger-Themen 5
M Fehler bei Thread.sleep() Java Basics - Anfänger-Themen 5
B Thread.sleep() Java Basics - Anfänger-Themen 1
C Thread.sleep ratsam? Java Basics - Anfänger-Themen 6
L Thread.sleep Java Basics - Anfänger-Themen 6
G problem mit thread.sleep() Java Basics - Anfänger-Themen 6
E Threads Verständnisfrage bzgl. Threads und Sleep Java Basics - Anfänger-Themen 2
M Threads Thread.Sleep Problem im Zusammenhang mit GUI/ActionPerformed-Methode Java Basics - Anfänger-Themen 4
S Methoden Warum ist sleep static? Java Basics - Anfänger-Themen 9
T Thread Sleep() Java Basics - Anfänger-Themen 4
J Thread.sleep Java Basics - Anfänger-Themen 7
F Sleep Funktion Java Basics - Anfänger-Themen 12
P Problem mit sleep Java Basics - Anfänger-Themen 24
S Thread.sleep () - Frage Java Basics - Anfänger-Themen 16
G Problem mit sleep() Methode Java Basics - Anfänger-Themen 7
M Frage zur Methode Thread.sleep() Java Basics - Anfänger-Themen 6
A [Fehlermeldung]Sleep-Befehl Java Basics - Anfänger-Themen 4
O Memory Thread.sleep() Java Basics - Anfänger-Themen 5
G Problem mit Thread Sleep! Java Basics - Anfänger-Themen 3
S Thread.sleep i.V.m Button.setText() Java Basics - Anfänger-Themen 8
G Schleife mit Thread.sleep pausieren Java Basics - Anfänger-Themen 12
M Zeitdifferenz von Ende - sleep(x) - Start von x abhängig Java Basics - Anfänger-Themen 6
M wait() sleep() geht nicht wirklich Java Basics - Anfänger-Themen 3
R Thread - sleep - interrupt Java Basics - Anfänger-Themen 18
S sleep()-Methode ? Java Basics - Anfänger-Themen 6
T for-Schleife durch sleep verzögern? Java Basics - Anfänger-Themen 1
M Thread.sleep(20) dauert 31ms ? Java Basics - Anfänger-Themen 7
E Anfänger Problem mit Thread.sleep() Java Basics - Anfänger-Themen 11
S Thread.sleep Java Basics - Anfänger-Themen 6
D extreme CPU Auslastung bei Sleep, etc. Java Basics - Anfänger-Themen 5
S Frage zu sleep() Java Basics - Anfänger-Themen 3
V Alternative zu Thread.sleep() ? Java Basics - Anfänger-Themen 6
F Sleep, pause, delay Java Basics - Anfänger-Themen 2
S Runtime.exec -> Thread.sleep -> Konflikt Java Basics - Anfänger-Themen 7
S sleep ohne runnable? Java Basics - Anfänger-Themen 8
A Thread.sleep Java Basics - Anfänger-Themen 9
W sleep "hängt" bei vielen Threads Java Basics - Anfänger-Themen 2
M sleep...?? Java Basics - Anfänger-Themen 2

Ähnliche Java Themen


Oben