Zeitsteuerung im Thread

Jaiel

Jaiel

Dauergast
235
Ich versuche einen Thread periodisch dazu aufzufordern etwas zu machen.

Ich schalte einfach an jedem Anfang einer schleife in der Run-Methode eine weitere schleife hinzu die so lange läuft bis ungefähr 40 ms in diesem fall vergangen sind

Code:
long delTime,oldTime=System.currentTimeMillis();
while(isRunning)
		{
			while(System.currentTimeMillis()-oldTime<30l)
			{
				try
				{
					sleep(20);
				}
				catch (InterruptedException e)
				{
					return;
				}
			}
			delTime=System.currentTimeMillis()-oldTime;
			if(delTime>50)delTime=50l;
			oldTime=System.currentTimeMillis();
			//update the canvas of the Surfaceview
			
		}



Meine Frage ist: Hat jemand was dagegen oder ist OK so!?:mad:
 
Das lässt sich auch ohne zweite schleife lösen, außerdem wäre der Annährungswert etwas regelmäßiger:

Code:
[LEFT]while(isRunning) { 
 long start = System.currentTimeMillis(); 
 //update the canvas of the Surfaceview
 long laufzeit = start - System.currentTimeMillis(); 
 if(laufzeit < 40) {
  try {
   Thread.sleep(40-laufzeit);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

irgendwie wird die Formatierung des codes zerstört, aber egal, er ist ja nicht so lang.[/LEFT]
 
Zuletzt bearbeitet:
ja na kalr das sit viel besser hab nicht daran gedacht:

Code:
long delTime=0,oldTime=System.currentTimeMillis();
		super.run();
		while(isRunning)
		{
			delTime=System.currentTimeMillis()-oldTime;
			if(delTime<40)
			{	
                                 try
				{
					sleep(40-delTime);
				}
				catch (InterruptedException e)
				{
					return;
				}
		
			        delTime=System.currentTimeMillis()-oldTime;
                        }
			if(delTime>50)delTime=50l;
			oldTime=System.currentTimeMillis();

                        updateTheCanvas(delTime);
			
		}


danke für die hilfe
 
Zuletzt bearbeitet:
Was bringt diese Zeile?
Code:
if(delTime>50)
delTime=50l;
 
Wahrscheinlich wurde das eingebaut damit die Schleife nach der Initialisierung durchlaufen wird. Aber das geht wirklich schöner :)
 
nein das ist dafür da damit ich kein zu großen delTime wert bekomme...könnte ja sein dass der thread etwas länger schlafen war weil andere prozesse die cpu brauchten

Der ursprüngliche Beitrag von 20:29 Uhr wurde um 20:30 Uhr ergänzt:

da ich es für ein spiel benutze und physik eine rolle spielt darf delTime nciht zu groß sein damit keine tunneleffekte auftreten und kollisionen verpasst werden könnten zum beispiel

Der ursprüngliche Beitrag von 20:30 Uhr wurde um 20:32 Uhr ergänzt:

missspelled schrieb:
Wahrscheinlich wurde das eingebaut damit die Schleife nach der Initialisierung durchlaufen wird. Aber das geht wirklich schöner :)

verstehe ich nicht ganz :) wird doch sowieso sofort durchlaufen weil delTime 1-2 ms sein wird
 
ja aber den Wert von 50 überschreibst du sofort wieder mit dem Beginn des nächsten Schleifendurchlaufs, ohne ihn zu verwenden. Außerdem verhindert if(delTime<40) ja bereits dass der thread überhaupt schläft falls delTime > 40.

p. s.
was macht super.run(); ?
 
kosmus schrieb:
ja aber den Wert von 50 überschreibst du sofort wieder mit dem Beginn des nächsten Schleifendurchlaufs, ohne ihn zu verwenden. Außerdem verhindert if(delTime<40) ja bereits dass der thread überhaupt schläft falls delTime > 40.

p. s.
was macht super.run(); ?
delTime wird benutzt in den weiteren operationen die ich kurz kommentiert habe(//update blablabla)
ich möchte eiin delTime wert zwischen 40 und 50 ms.geh mal die schleife im kopf durch ist delTime kleienr als 40 sagen wir 30ms wenn die schleife (wieder) beginnt weil die aktionen ganz unten sehr schnell ausgeführt wurden(//update the canvas) dann schläft er und macht einen neuen delTime....so, ist nach dem schlafen der wert über 50ms initialisiere ich delTime mit 50ms.oldtime wird gesetzt um wieder messen zu können wie lange die operationen des updates gebracuht ahben.

ist jetzt delTime über 40 und sogar über 50 wird der Thread nciht schlafen gelegt und auf 50 zurückgesetzt. ist delTime konsant zwischen 40 und 50 ms bei jeden schleifendurch gang dann sit alles ok thread wird nciht schlafen gelegt delTime wird so benutzt wie es ist...hoffe jetzt leuchtet es ein.



super.run(); ist immer zu callen bei Threads!!!

Der ursprüngliche Beitrag von 21:01 Uhr wurde um 21:05 Uhr ergänzt:

ich hab oben den code jetzt abgeändert damit du sehen kannst das ich delTime sehr wohl benutze :)
 
Ok dann lass mal deine Schleife zeile für zeile durchgehen
1.
delTime=System.currentTimeMillis()-oldTime;

beim ersten durchlauf wird delTime etwa bei 0 - 2 liegen weil oldTime kurz vor schleifenbeginn belegt wurde und etwa den gleichen wert hat wie System.currentTimeMillis();

if(delTime<40) {... sleep ...}
delTime<40 ist true und der Thread schläft für etwa 40 ms.

if(delTime>50)delTime=50l;
delTime ist ja wie gesagt zwischen 0 und 2 in sofern passiert hier erstmal nichts.

oldTime=System.currentTimeMillis();
oldTime ist etwa 40 größer als vorher

update canvas ... ok das kann dauern vielleicht mehr als 40 ms vielleicht weniger als 40 ms.. sagen wir mal es dauert mehr als 40 ms

zweiter schleife lauf beginnt :

delTime=System.currentTimeMillis()-oldTime;
da zwischen oldTime und currentTime mehr als 40 ms ist delTime > 40

if(delTime<40) {... sleep ...}
delTime ist > 40 also schläft der Thread nicht und es geht weiter mit


if(delTime>50)delTime=50l;
sagen wir mal das delTime ist auch > 50 und wird auf 50 gesetzt.

oldTime=System.currentTimeMillis();
oldTime wird wieder aktualisiert

update canvas ...

3. durchlauf
delTime=System.currentTimeMillis()-oldTime;
delTime wird neu belegt und dein delTime=50 bleibt ohne Effekt (egal ob das canvaszeichen nun 1ms, 40ms oder 120ms gedauert hat).



und super.run()
bezieht sich vermutlich auf das Interface Runnable und Interfaces haben bekanntlich keine ausprogrammierten Methoden also passiert hier gar nichts, außer du hast noch eine Vererbung dazwischen, die ich nicht sehen kann, weil ich nicht das ganze coding kenne, deshalb habe ich gefragt was super.run() gerade tut.

--- Edit ---
mir war nicht klar das du delTime weiter gibst, dann macht die zeile natürlich Sinn
 
Jaiel schrieb:
super.run(); ist immer zu callen bei Threads!!!
Das ist schlicht falsch. "super" verwendet man, um in der Subklasse Methoden der Superklasse aufzurufen.
Genauso falsch ist, wenn man run() anstatt start() aufruft.
Wenn du run() aufrufst, wird die run-Methode sequenziell abgearbeitet und nicht nebenläufig. (außer das will man explizit o.ô)
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: kosmus
kosmus schrieb:
if(delTime>50)delTime=50l;
delTime ist ja wie gesagt zwischen 0 und 2 in sofern passiert hier erstmal nichts.


das ist falsch...guck dir noch mal die if anweisung GENAU an ich setze am Ende des Schlafens delTime wieder neu ;)

Der ursprüngliche Beitrag von 22:02 Uhr wurde um 22:03 Uhr ergänzt:

KatyB schrieb:
Wenn du run() aufrufst, wird die run-Methode sequenziell abgearbeitet und nicht nebenläufig. (außer das will man explizit o.ô)

habe nie erwähnt dass ich run aufrufe;)
ist mir schon klar dass ich start() aufrufen muss

Der ursprüngliche Beitrag von 22:03 Uhr wurde um 22:08 Uhr ergänzt:

kosmus schrieb:
3. durchlauf
delTime=System.currentTimeMillis()-oldTime;
delTime wird neu belegt und dein delTime=50 bleibt ohne Effekt (egal ob das canvaszeichen nun 1ms, 40ms oder 120ms gedauert hat).

die 50 ms wurden ja benutzt um den canvas zu aktualisieren ich brauche den alten wert ja nciht

delTime setzte ich doch immer wieder nue um die zeitspanne zu bekommen die das zeichnen gebraucht hat:thumbsup:

Der ursprüngliche Beitrag von 22:08 Uhr wurde um 22:25 Uhr ergänzt:

das mit suiper.run() hab ich mal irgendwo aufgeschnappt es macht einfach die standard implementierung für den Thread

ist vielleicht sowas ähnliches wie bei onCreate(9 zum Beispiel oder so da ruft man ja auch super.onCreate () auf
 
Mein Beitrag hatte ich angefangen zu schreiben bevor du den code aktualisiert hast, ich wusste also nicht das du delTime weiter gibst. Dieses neubestzen innerhalb der Schleife habe ich tatsächlich über lesen. Insgesamt hat diese Diskussion ein Richtung erreicht, für die ich kein Verständnis habe. Du hast nach Optimierung deines Codes gefragt, ich habe dir gesagt, was ich anderes machen würde. Daraufhin postest du wieder code, ich habe angenommen du möchtest weitere Tipps. Ich habe zwei Zeilen nicht nachvollziehen können (mangels Kenntnis des weiteren Codes) und nachgefragt. Diese Fragen waren auch gar nicht wertend gemeint und hoffentlich auch nicht so formuliert.

Ich vermute das da weitere Optimierungen möglich sind, aber der angeschlagene Ton verdirbt mir die Lust mich weiter damit zu beschäftigen.
 
hey sorry aber das verstehe ich jetzt nicht wie ich dich verärgert haben könnte war jedenfalls nciht meine absicht.
den code habe ich wirklich nur einmal editiert und zwar vor deinem post schon sonst hab ich ihn nciht angefasst(ausser du hast 23 minuten an deinem post gearbeitet)

ok sorry falls ich etwas geschrieben habe was dir einen falschen ton vermittelt haben könnte

Der ursprüngliche Beitrag von 00:45 Uhr wurde um 00:46 Uhr ergänzt:

ich danke dir auf jeden fall trotzdem für den hinweis die schleife wegzumachen am anfang
 
Ja ist OK, vielleicht habe ich es auch falsch aufgefasst.

Wie auch immer, wenn dein Coding zu deiner Zufriedenheit funktioniert, ist ja alles ok.
 
Jo funktioniert perfekt und ich finde das besser als einen Timer zu benutzen und sowie ich den sourcecode des Timers studiert habe auch effizienter weil er genau meine speziellen Bedürfnisse erfüllt
 

Ähnliche Themen

D
  • djsnoopy
Antworten
6
Aufrufe
616
djsnoopy
D
S
Antworten
8
Aufrufe
511
swa00
swa00
W
  • waltsoft
Antworten
3
Aufrufe
722
waltsoft
W
Zurück
Oben Unten