# Schlaf-Thread aufwecken



## me.toString (12. Jul 2006)

Moin
ich habe eine Anwendung, die alle 8 Minuten etwas tut. Wenn sie damit fertig ist, dann lege ich sie schlafen mittels

```
try{
   Thread.sleep( schlafzeit );
}
...
```
Das funzt auch ganz gut ... nur möchte ich von aussen her den Schlafzyklus unterbrechen, damit ich bei Konfigurationsänderungen nicht immer 8 Minuten warten muss, ob's funzt.
Wie mache ich das?


----------



## Dit (12. Jul 2006)

von aussen?  ???:L 

wenn ich das dann richtig verstehe kannst du "schlafzeit" doch nen Wert mit geben
(int schlafzeit

und denn trägst du dann von "aussen" :wink:  ein


----------



## Dit (12. Jul 2006)

http://www.addison-wesley.de/service/Krueger/kap10002.htm#E14E94

das steht das drin!
Stop müsste das dann sein! schau mal reiN!


----------



## foobar (12. Jul 2006)

Wenn du alle n-Minuten eine aktion ausführen willst ist ein Timer viel besser geeignet.

@Dit stop() ist deprecated und wurde durch interrrupt() ersetzt.


----------



## me.toString (12. Jul 2006)

Von außen heißt: 
Der Prozess läuft den ganzen Tag rund um die Uhr und macht fleißig seine Arbeit (so soll's ja auch sein ;o)
Aber nun will der Kunde von außen (das ist eine separate Webanwendung) den Schlaf abbrechen (verkürzen passt glaube besser). In der Webanwendung kann man die Anwendungs konfigurieren und der laufenden Anwendung via Socket-Kommunikation zu verstehen geben: Schlaf beenden und mache sofort weiter. 
Die Anwendung und die Kommunikation läuft super ... aber nun muss ich dem Timerthread, der normaler weise die ganzen zeitlichen Abläufe koordiniert aber in dem Moment seinen Schönheitsschlaf abhält, aufwecken ... aber wie? Wie kann man Thread.sleep() davon überzeugen nicht mehr weiter zu machen?

> wenn ich das dann richtig verstehe kannst du "schlafzeit" doch nen Wert mit geben
> (int schlafzeit
>
> und denn trägst du dann von "aussen"  :wink: ein
Die Idee ist nicht schlecht ... aber wenn ich von "aussen" zugreifen will, dann schläft die Anwendung schon tief und fest.


----------



## Dit (12. Jul 2006)

habe noch nie mit sleep gearbeitet 
aber denbar wäre es doch in einer if schleife
lauf so lange bis z.B. false --> abbruch gedrückt wurde....

mit dem Zugriff kann ich dir leider auch nicht sagen ob das Programm überhaupt reagiert aber hast du es denn mal mit

interrrupt() 

versucht...
sonst google mal da findet du bestimmt was!


----------



## Murray (12. Jul 2006)

Du kannst statt Thread#sleep Object#wait verwenden. Damit wird solange gewartet, bis entweder die angegebene Zeitspanne verstrichen ist, oder aber die Warterei explizit per Object#notify beendet wurde.

BSp.:

```
public class Test implements Runnable {


	public Test() {
	
		new Thread( this).start();
	
		while ( true) {
			long t0 = System.currentTimeMillis();
			try {
				synchronized( this) {
					this.wait( 2000);
				}
			} catch ( InterruptedException ie) {
				ie.printStackTrace();
			}
			System.out.println( "waited " + (System.currentTimeMillis()-t0) + " ms");
		}
	
	}
	
	public void run() {
		while( true) {
			try {
				Thread.sleep( 3000);
				synchronized( this) {
					this.notify();
				}
				Thread.sleep( 500);
				synchronized( this) {
					this.notify();
				}
			} catch ( InterruptedException ie) {
				ie.printStackTrace();
			}
		}
	}
	
	
	public static void main( String[] args) {
		new Test();
	}
}
```


----------



## me.toString (12. Jul 2006)

Danke Murray ... ich glaube, dass ist genau die Lösung für mein Problem!


----------



## Leroy42 (12. Jul 2006)

Och Jungs, warum so umständlich?   

Ist euch noch nie aufgefallen, daß man einen Aufruf von sleep mit einem try-catch-Block
umgeben muß?


```
try {
    Thread.sleep(4242);
} catch (InterruptedException e) {
  // hier steht meistens nichts drin
}
```

Genau diese Exception wird aufgerufen wenn man von
außen, innen, von der Seite oder von sonstwo die interrupt-Methode
des Threads aufruft.


----------



## Murray (12. Jul 2006)

@Leroy
Klar, aber um interrupt aufrufen zu können, muss man ja eine Referenz auf den Thread haben, den man woanders "schlafengelegt" hat. Insofern wird das nicht viel einfacher als wait/notify.


----------



## Roar (12. Jul 2006)

doch, der code in der Thread klasse beschränkt sich dann nämlich nur auf das notwenidigste, und inwiefern ist es kompliziert eine Referenz zu halten? ;-)


----------



## Murray (12. Jul 2006)

Selbstverständlich ist es nicht kompliziert, eine Referenz zu halten (ich glaube auch nicht, so etwas jemals behauptet zu haben). Ich meine nur, dass der Code dann der Lösung mit wait/notify recht ähnlich sehen wird.


----------



## Roar (12. Jul 2006)

naja nö, dann braucht man kein wait notify mehr:


```
public void run() {
while(true) {
try {
Thread.sleep(zeit);
} catch(InterruptedException e) {
continue;
}
arbeite();
}

... woanders...
thread.neueZeit(zeit);
thread.interrupt();
```


----------



## me.toString (13. Jul 2006)

Ich wusste ja gar net, dass es mehrere Möglichkeiten gibt. 
Hab mich jetzt für letztere Lösung (von Roar) entschieden, da die noch besser in mein Konzept passt (und sie ist auch noch einfacher umzusetzen)

!!! Danke an alle !!!!!


----------



## Guest (8. Jan 2007)

Bin auf der Suche nach einer Lösung für ein sehr ähnliches Problem via Forensuche hier gelandet und konnte es damit auch wunderbar lösen!!!


Jetzt hab ich allerdings noch eine kleine Frage dazu: 

Was passiert, wenn ich interrupt() aufrufen, aber andere Thread garnicht schläft? Sollte/Kann ich irgendwie überprüfen, ob der Thread, denn ich aufwecken will, überhaupt schläft?


grüße

basti


----------



## Waldbeere (8. Jan 2007)

Hiho, 

soweit ich weiss sollte nichts passieren, wenn der Thread nicht schläft
bzw. wartet. Es wird nur ein Flag gesetzt das interrupt aufgerufen
wurde, dieses kannst Du dann mit isInterrruped() abfragen und ensprechend
reagieren.


----------



## Guest (8. Jan 2007)

Hmm ok, deine erste Aussage verstehe ich. Wenn "nichts" passiert, dann ist ja alles wunderbar und ich bin fertig 


Aber was meinst du mit:



> ... dieses kannst Du dann mit isInterrruped() abfragen und ensprechend reagieren.



Wenn mein Thread doch schläft, kann ich doch keine Flag abfragen? Wach wird der doch dann im try cathc Block?!


----------



## Waldbeere (8. Jan 2007)

Na,

ich meinte wenn er wach ist und Du aus irgendeinem Grund interrupt aufrufst, könntest
Du darauf reagieren.


----------



## Beni (8. Jan 2007)

Ein schlafender Thread auf den "interrupt" angewendet wird, wacht tatsächlich auf. Mit einer "InterruptedException" :wink:


----------



## Guest (9. Jan 2007)

> Ein schlafender Thread auf den "interrupt" angewendet wird, wacht tatsächlich auf. Mit einer "InterruptedException"



Und was macht ein wacher Thread?! Treten da Komplikationen auf? 

Hab das Ganze mal ausprobiert und konnte keine Probleme festgestellt (z.B.: unerwünschte Interuted Exception), wollte aber auf Nummer sicher gehn und fragen, ob ich die Eigenschaft des Threads, auf den interrupt angewendet wird, prüfen muss.


----------



## Beni (9. Jan 2007)

Ups, ich habe die Frage falsch verstanden (und dazu noch übersehen, dass wir hier schon auf der zweiten Seite sind) :-(

Ein wacher Thread läuft einfach weiter, aber der "inerrupted"-Flag wird gesetzt. Im Thread kann man über "Thread#isInterrupted()" das Flag abfragen, und mit "Thread#interrupted()" kann man es sogar wieder deaktivieren.


----------



## Guest (9. Jan 2007)

Super, genau das wollte ich wissen!

Danke


----------

