run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird.

Nun, normalerweise fängt man damit an, dass man weiß, wie man einen Thread erstellt.

Am einfachsten mit einer Klasse, die Runable implementiert. Anschließend durch einen Thread ausgeführt wird.

Dann kann man schauen, wie ich kann ich den Thread pausieren. Vielleicht sowas wie "Wait in java".
 
Nun, normalerweise fängt man damit an, dass man weiß, wie man einen Thread erstellt.

Am einfachsten mit einer Klasse, die Runable implementiert. Anschließend durch einen Thread ausgeführt wird.

Dann kann man schauen, wie ich kann ich den Thread pausieren. Vielleicht sowas wie "Wait in java".
Also einen Thread kann ich erstellen, dass ist kein Problem. Aber warum pausieren?

Ich soll doch etwas pro Sekunde aufrufen und nicht pausieren?
 
Das kann man sich ja doch bildlich vorstellen. Du sollst in einer bestimmten Zeit x Bierkästen stapeln. Also sagen wir mal in 1 Stunde 10 Kästen irgendwo stapeln. Nicht mehr …

Was machst du? Wie gehst du vor?
 
Hi, ich soll 30x die Sekunde eine Methode aufrufen, das soll ich in der run-Methode eines Threads realisieren, aber wie macht man sowas?

Also, Grundwissen. Eine CPU fuehrt Instruktionen aus, nicht mehr und nicht weniger. Wie schnell diese dies tut haengt vom Takt der CPU ab. Also ich ziehe mir jetzt zahlen aus dem Hintern, sagen mir mal mit einer 5MHz CPU koennen wir 1 Million Instruktionen die Sekunde ausfuehren. Dann koennen wir mit einer modernen 3,5GHz CPU in etwa 700 Millionen Instruktionen die Sekunde ausfuehren. In der Natuer der Sache liegt dass die CPU Instruktionen immer so schnell ausfuehrt wie moeglich, wir wollen das so, weil wir wollen dass die CPU schnell ist.

Jetzt kommst du mit deinem Methodenaufruf daher der vielleicht 15 Instruktionen kostet, das bedeutet dass eine moderne CPU diesen Aufruf immerhin stolze 46 Millionen mal die Sekunde ausfuehren kann...du willst aber nur 30 mal. Das bedeutet entweder du taktest deine CPU so herunter dass du genau 30 mal die Sekunde triffst, von Machbarkeit mal abgesehen, wuerde ich davon abraten. Oder du bremst die Ausfuehrung so aus dass der Aufruf nur 30 mal die Sekunden passiert. Wenn wir jetzt die Ausfuehrzeit der Methode vernachlaessigen, bedeutet das dass wir ein Zeitfenster von 33,333 Millisekunden je Ausfuehrung haben, wir muessen also der CPU sagen "fuehre dies nur alle 33 Millisekunden aus". Denn nur dann haben wir es 30 mal pro Sekunden ausgefuehrt.

Wie macht man das? Man ruft die Methode auf, und wartet dann 33 Millisekunden bevor man die Methode wieder aufruft. Und das ist was die anderen versuchen dir zu sagen. Stell dir das halt wie eine Trommel vor. Du sollst 20 mal die Minute die Trommel schlagen in regelmaeszigen Abstaenden. Klar kannst du die Trommel auch 5 mal die Sekunde schlagen, dies ist dir rein physisch moeglich, aber du sollst ja nur 20 mal in der Minute d'rauf schlagen. Also musst du 5 Sekunden zwischen jedem Schlag warten.

wie schnell ist eine endlos schleife?

Mein Heim-PC schafft eine Endlosschleife in 7 Minuten.
 
Mein Heim-PC schafft eine Endlosschleife in 7 Minuten.
Ich bin mir nicht sicher, ob das gut oder schlecht ist ,...

Die Endlosschleife, die den Stack mit Aufrufen füllt, läuft bei mir nicht so lange. Ist mein Rechner schneller? Oder hast Du einfach soviel Hauptspeicher, dass es dann 7 Minuten dauert, bis deine x TB Ram (die Du der JVM auch gegeben hast) voll sind? 🙂
 
Hmm, das Problem ist, wir haben die Klasse Timer nicht kennengelernt, deshalb bin ich mir relativ unsicher, ob wir das benutzen dürfen.

Also bin mir eher sicher, dass wir Timer nicht benutzen dürfen, obwohl ich die Klasse kenen. Wie soll ich dann das ohne einen Timer hinebkommen? (wir dürfen aber sleep von threads nutzen)
 
Hmm, das Problem ist, wir haben die Klasse Timer nicht kennengelernt, deshalb bin ich mir relativ unsicher, ob wir das benutzen dürfen.

Also bin mir eher sicher, dass wir Timer nicht benutzen dürfen, obwohl ich die Klasse kenen. Wie soll ich dann das ohne einen Timer hinebkommen? (wir dürfen aber sleep von threads nutzen)
genau das solltest du dir überlegen! Und einige Anregungen hast du bereits bekommen.

Hast du schon was ausprobiert? Wenn ja: was? Wenn nein: wann willst du endlich anfangen?
 
genau das solltest du dir überlegen! Und einige Anregungen hast du bereits bekommen.

Hast du schon was ausprobiert? Wenn ja: was? Wenn nein: wann willst du endlich anfangen?
Ich probier das seit gefühlt 2 Std hahahaha. Was überlegt, einen Haufen sogar. Was gebracht -->eher weniger


Also, was ich mir gedacht habe, ich schau, wie viele Befehle meine Cpu in der Sekunde erledigt, wenn er z. B. sehr klein geschätzt 60 Stück pro Sekunde schaft, lass ich ihn eine halbe Sekunde schlafen und hätte dann ja in der Sekunde 30 wiederholungen?
 
Hi, ich soll 30x die Sekunde eine Methode aufrufen, das soll ich in der run-Methode eines Threads realisieren, aber wie macht man sowas?
Du sagst Thread erstellen kannst du.

Was brauchst du noch ? Es soll mindestens 30 x durchlaufen. Was könnte das sein
In welcher Maßeinheit gibst du die Wartezeit an?

Da sind Sachen die du dir selber beantworten kannst.

Wenn du noch nicht mal einen Anfang „Code“ liefen kannst wird hier keiner mehr helfen.
 
Du sagst Thread erstellen kannst du.

Was brauchst du noch ? Es soll mindestens 30 x durchlaufen. Was könnte das sein
In welcher Maßeinheit gibst du die Wartezeit an?

Da sind Sachen die du dir selber beantworten kannst.

Wenn du noch nicht mal einen Anfang „Code“ liefen kannst wird hier keiner mehr helfen.
Ich gebe dir ein Beispiel, wenn ich nun z. B. sleep mit 100 mache, so schläft die Methode halt für eine Sekunde, mehr aber auch nicht.

Ich kann jha so nciht sagen, dass er nur 50x in der Sekunde etwas tun soll oder?
 
Danke euch beiden glaube jedoch dass das so nicht geht oder:


Java:
for(int i = 0; i < 30; i++) {
    // Tue etwas
    Thread.sleep(1000 / 30);
}

Weil hier sgae ich einfach, dass ich die Sekunde durch 30 teile. Aber durch die Schleife führe ich das ja dann 30x aus.
Und ich soll jede Sekunde das 50x wiederholen und nicht nur 30x oder?
 
Du wartest doch genau 33 Millisekunden. Ist ein Tackt von ca 30 Hertz.
korrekt, aber:
"Der Thread soll 30 Mal pro Sekunde die Methode ... aufrufen"

Kann ich da einfach dann 1000/30 machen? So einfach? Und wie lange läuft überhaupt der Thread? Sagt die Aufgabenstellung ich soll nur das 30x ausgeben? Und dann den thread beenden oder soll ich den Thread länger laufen lassen und jede Sekunde 30x ausgeben?
 
a) jetzt wurde dem TE wieder die Lösung gegeben ... Lerneffekt also vermutlich gleich 0 und ihr könnt ihm dann die direkt die nächste Aufgabe lösen ...

b) die angebotene Lösung impliziert aber, dass, dass der Methodenaufruf keine Zeit verbraucht. Das ist natürlich unrealistisch. Beispiel: wenn der Aufruf 10ms brauchen würde, dann hättet ihr 30*10ms Laufzeit durch die Methode und 1000ms/30*30 Wartezeit. Dadurch ergibt sich dann eine Ausführung von 30 Aufrufen in 1,3s und nicht in 1s.

Ob dies die erwünschte Lösung ist oder nicht kann ich so nicht sagen. So dies wirklich noch ganz am Anfang ist, dann kann das durchaus so beabsichtigt sein. (Und so da nur eine kleine Ausgabe gemacht wird, dann ist die Zeit vermutlich auch vernachlässigbar und das Sleep selbst ist ja auch erst einmal relativ ungenau.)
 
a) jetzt wurde dem TE wieder die Lösung gegeben ... Lerneffekt also vermutlich gleich 0 und ihr könnt ihm dann die direkt die nächste Aufgabe lösen ...

Ja, manchmal denkt man, dass man damit hilft aber hier ist dem wohl nicht so 😉

@TO: Ich weiß nicht, in welchem Kontext du Java lernen möchtest, aber du musst viel selbstständiger sein, sonst wird das nichts.
 
Ja, manchmal denkt man, dass man damit hilft aber hier ist dem wohl nicht so 😉
Das ist ja eigentlich in jedem seiner Threads so. Das ist halt, was etwas auffällt. Und das ist schade. Denn man kann sich alles selbst erarbeiten.

Das war ja ein Versuch mit dem bildlichen Ansatz von mir, der irgendwie komplett ignoriert wurde.
Das kann man sich ja doch bildlich vorstellen. Du sollst in einer bestimmten Zeit x Bierkästen stapeln. Also sagen wir mal in 1 Stunde 10 Kästen irgendwo stapeln. Nicht mehr …

Was machst du? Wie gehst du vor?
Die Vorgabe muss man erst einmal genau sehen: Es geht um die 10 Kästen in 1 Stunde. Es geht nicht um alle 6 Minuten ein Kasten. Das geht, aber das muss nicht sein.

Wie macht man das? Da schaue ich auf die Uhr: Wie spät ist es?
Dann stapel ich die 10 Kästen.
Dann schaue ich wieder auf die Uhr: Dann sehe ich, wie lange ich "chillen" kann. Das trage ich mir dann als Timer im Handy ein und chille ....
==> Lösung fertig.

Aber wenn ich zu der Lösung komme: Ich stapel einen Kasten und dann chille ich 6 Minuten, dann habe ich ein Problem. Ich bin halt lahm und brauche zum Stapeln einer Kiste 1 Minute ...
==> Problem der vorgestellten Lösung.

Und man kann auch noch sehen: Wenn ich das ganz lange mache, dann verschlimmert sich das mit jedem Durchgang!

Und das ist doch sowas von bildlich. Das sollte man sich doch vorstellen können. Und auch das Vorgehen sollte man nachvollziehen können. Und das ganz ohne zu programmieren. Den Algorithmus muss man dann noch in Java schreiben. Aber das wird ganz einfach, denn ich habe die genaue Vorstellung des Algorithmus erarbeitet.

Und mit dem auf die Uhr schauen wird jede Abweichung auch wieder korrigiert. Wenn ich bei einem Durchgang etwas zu langsam war, dann habe ich aber die Ursprüngliche Anfangszeit und kann da ja immer den genauen Soll-Zeitpunkt nehmen. Also wenn es zum "chillen" kommt, gehe ich jedes mal auf die genau berechnete Endezeit. Ein Fehler von vorherigen Durchläufen wird also immer korrigiert.
 
Das ist ja eigentlich in jedem seiner Threads so. Das ist halt, was etwas auffällt. Und das ist schade. Denn man kann sich alles selbst erarbeiten.

Das war ja ein Versuch mit dem bildlichen Ansatz von mir, der irgendwie komplett ignoriert wurde.

Die Vorgabe muss man erst einmal genau sehen: Es geht um die 10 Kästen in 1 Stunde. Es geht nicht um alle 6 Minuten ein Kasten. Das geht, aber das muss nicht sein.

Wie macht man das? Da schaue ich auf die Uhr: Wie spät ist es?
Dann stapel ich die 10 Kästen.
Dann schaue ich wieder auf die Uhr: Dann sehe ich, wie lange ich "chillen" kann. Das trage ich mir dann als Timer im Handy ein und chille ....
==> Lösung fertig.

Aber wenn ich zu der Lösung komme: Ich stapel einen Kasten und dann chille ich 6 Minuten, dann habe ich ein Problem. Ich bin halt lahm und brauche zum Stapeln einer Kiste 1 Minute ...
==> Problem der vorgestellten Lösung.

Und man kann auch noch sehen: Wenn ich das ganz lange mache, dann verschlimmert sich das mit jedem Durchgang!

Und das ist doch sowas von bildlich. Das sollte man sich doch vorstellen können. Und auch das Vorgehen sollte man nachvollziehen können. Und das ganz ohne zu programmieren. Den Algorithmus muss man dann noch in Java schreiben. Aber das wird ganz einfach, denn ich habe die genaue Vorstellung des Algorithmus erarbeitet.

Und mit dem auf die Uhr schauen wird jede Abweichung auch wieder korrigiert. Wenn ich bei einem Durchgang etwas zu langsam war, dann habe ich aber die Ursprüngliche Anfangszeit und kann da ja immer den genauen Soll-Zeitpunkt nehmen. Also wenn es zum "chillen" kommt, gehe ich jedes mal auf die genau berechnete Endezeit. Ein Fehler von vorherigen Durchläufen wird also immer korrigiert.
Danke, aber man glaubt mir nicht, aber ich persönlich habe als erstes an das gedacht, was er da geschrieben hat, akls mir jemand gesagt hat, das gehe auch mit sleep, aber kann das irgendwie nicht fassen, dass das die Lösung ist. Warum:

Beipsiel.

Methode{

hier tue ich etwas
....
sleep(1000/30)
}

Was ist nun das Problem an dieser Lösung, bei dem Teil, wo ich etwas tue, das hat mich ja auch Sekunden gekostet.

Das heißt, ich müsste die Zeit die ich hier:

Methode {

hier tue ich etwas //hier
... //hier
sleep(1000/30)
}

"verschwendet" habe, abziehen.

Nur dann hätte ich ja wirklich das geschafft. Und darauf komme ich ehrlich gesagt nicht



AUßerdem, wäre eine Endlosschleife nicht noch besser?

Wenn ich sowas machen würde

Java:
while(true){

    //Hier was ich mache



    sleep(1000/30)

}
 
Zuletzt bearbeitet:
Ein Microbenchmark ist nicht notwendig. So könnte man mit System.currentTimeMillis arbeiten um möglichst nah ran zu kommen.

Und wenn die gleichmäßige Verteilung nicht notwendig ist, wird der Overhead auch nicht groß.
 
Spiel es doch durch oder schau Dir das visuelle Beispiel mit den Bierkisten an. Du hast einen einmaligen Startpunkt und dann nur noch jeweils ein Messpunkt vor dem Sleep. Und dann kannst du berechnen, wie lange der Thread noch schlafen muss.

Man muss aber aufpassen: je kleiner die Zeitintervallen werden, desto schwieriger. Aber da wird auch das Thread.sleep problematisch, weil das auch ungenau wird. Wenn das System nur Schritte mit x ms schafft, dann hast du das Limit in der Regel auch im Thread.sleep. So wie das System nicht die Uhr schneller umstellen kann ist es auch nicht möglich, einen Thread zu wecken.
 
Darauf kann es dir hier nicht ankommen.

Du müsstest in der Methode ein Mircobenchmark durchführen. Und das in Java nicht möglich.
Genau 30 mal pro Sekunde ist zwar nicht möglich. Aber eine annähernd konstante Schleife zu erstellen schon.
Was ist nun das Problem an dieser Lösung, bei dem Teil, wo ich etwas tue, das hat mich ja auch Sekunden gekostet.

Das heißt, ich müsste die Zeit die ich hier:

Methode {

hier tue ich etwas //hier
... //hier
sleep(1000/30)
}

"verschwendet" habe, abziehen.
Der TE hat recht damit wenn, er die verstrichene Zeit misst und den Sleep entsprechend adaptiert.
Das ist aber nur eine der notwendigen Techniken um einen annähernd konstanten Schleife zu machen.
Es ist bei einem Gameloop notwendig den Code dahingehend zu optimieren, um ein ruckelfreies Spiel zu machen.
Dieser Asteroidclone läuft unter Swing mit 80 fps
https://www.java-forum.org/thema/spielesammelthread.123839/#post-1288802
 

Zurück
Oben