PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java] Zeitdifferenz messen zwischen Programmstart und Laufzeit ...


Captain America
2005-09-23, 00:58:49
... auch wenn die Uhr verstellt wird.

Wie kann ich in Java messen, wie viele (Milli-) Sekunden mein Programm läuft, zuverlässig auch wenn die Systemuhr verstellt wird? Mit System.currentTimeMillis() lässt dich das offensichtlich nicht korrekt berechnen, wenn jemand die Uhr um eine relative Differenz zurückstellt, die grösser ist, als die absolute Laufzeit. :ugly:

Jemand ne Idee? thx

Senior Sanchez
2005-09-23, 01:05:56
Hmm, ist ne gute Frage. Ich dachte bisher, dass System.currentTimeMillis gar nicht auf die interne Uhr zurückgreift, aber irgendwoher muss das Teil ja an seine Zeit kommen :uponder:

Es gibt ne dirrrrty Variante wo ich auch sagen kann, dass die nciht hundertprozentig genau ist.

Mach nen Thread mit einer relativ hohen Priorität, der eine programminterne Uhrzeit in einer Art counter verwaltet. Lass den Thread meinetwegen alle 100 ms schlafen und danach erhöhste eine long variable immer um 100. Diese Variable speichert dann sozusagen die Laufzeit.

Problematisch dabei ist allerdings, dass ein Thread nicht exakt 100 ms schlafen muss. Es kann auch mehr oder ein bissl weniger sein, wodurch es zu abweichungen kommt. Um das möglichst einzugrenzen, sollte der halt auf ner hohen Priorität laufen.

Captain America
2005-09-23, 01:08:00
interessanter ansatz, aber ist mir zu ungenau und verschwenderisch. :usad: kleines verwöhntes script kiddie ich bin :ugly2:

Senior Sanchez
2005-09-23, 01:19:02
interessanter ansatz, aber ist mir zu ungenau und verschwenderisch. :usad: kleines verwöhntes script kiddie ich bin :ugly2:

Den habe ich mal implementiert und innerhalb gewisser Toleranzen funktioniert das auch ziemlich gut.

Aber ich habe noch ne andere Idee.

Du mischt am besten beide Varianten und bekommst somit ne relativ stabile und unabhängige Variante. Dazu brauchst du einen Thread, der in konstanten Abständen System.currentTimeMillis() abruft und auch den Wert von der letzten System.currentTimeMillis() speichert. Weiterhin brauchste ne long-Variable die die verstrichene Zeit speichert. Der Thread bildet einfach bei jedem Erwachen ausm Schlaf die Differenz zwischen der aktuellen und der letzten Zeit. Stellt er fest, dass die aktuelle Angabe kleiner ist, als die vorige, so wurde die Uhr verstellt und es wird davon ausgegangen dass der ganze Prozess genau der Schlafzeit des Threads entspricht.
Es wird ja auch nicht ständig die Uhrzeit verstellt, deswegen kannste meist die Differenz zwischen dem letzten System.currentTimeMillis() und dem aktuellen bilden. Diese Variante dürfte recht genau sein.

Senior Sanchez
2005-09-23, 01:27:35
Da ich meinen Beitrag komischerweise nicht editieren kann, versuch ichs mal so.

mal nen schneller Hack, weiß net obs so direkt klappt.


public class TimeThread extends Thread {

private long last = 0;
private long time = 0;
private long sleeptime = 0;

public void run() {
last = System.currentTimeMillis();

try {
while(true) {
sleep(sleeptime);

long cur = System.currentTimeMillis();
time += (cur > last)?cur-last:sleeptime;
last = cur;
}
}
catch(Exception e) {
this.interrupt();
}


}

}




EDIT: Interessant wäre jetzt natürlich ob das sleepen durch die Zeitumstellung auch beeinflusst wird.

HellHorse
2005-09-23, 08:34:24
JMX (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/RuntimeMXBean.html#getUptime()), sollte gehen, ob's auch richtig implementiert ist, ist ne andere Frage.
Alternativ kannst du System.nanoTime() (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#nanoTime()) probieren.

Trap
2005-09-23, 09:51:43
time += (cur > last)?cur-last:sleeptime;
Das geht beim Uhrzeit nach vorne stellen schief.

Senior Sanchez
2005-09-23, 09:54:41
Das geht beim Uhrzeit nach vorne stellen schief.

Stimmt, jetzt wo du es sagst.

HellHorse
2005-09-23, 10:53:37
EDIT: Interessant wäre jetzt natürlich ob das sleepen durch die Zeitumstellung auch beeinflusst wird.
Seit heute nicht mehr :D
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6311057

Senior Sanchez
2005-09-23, 10:57:53
War das jetzt da irgendwie nen Kernel-Problem? *g* Weil da unten steht ja fixed.

Der Bug wurde ja reported und auf 1.5er JDK schlägts fehl, aber auf nem 1.4.2er läufts dagegen. Ist das Problem damit gelöst, oder besteht der Bug nun weiterhin? *g*

Ist aber nen geniales Timing, gerade wenn wir uns hier diese Frage stellen, kommt das *g*

HellHorse
2005-09-23, 12:20:37
War das jetzt da irgendwie nen Kernel-Problem? *g*
Nee vermutlich nicht, eventuell nahm man einfach die falsche API. Das kommt bei Sun hin und wieder vor.

Der Bug wurde ja reported und auf 1.5er JDK schlägts fehl, aber auf nem 1.4.2er läufts dagegen.
Ja, das ist strange.

Ist das Problem damit gelöst, oder besteht der Bug nun weiterhin? *g*
Release Fixed: mustang(b53)
Allerdings scheint der Fix einen 2.6er Kernel zu benötigen.

Shink
2005-09-23, 14:37:23
interessanter ansatz, aber ist mir zu ungenau und verschwenderisch. :usad: kleines verwöhntes script kiddie ich bin :ugly2:
Naja, so verschwenderisch ists auch wieder nicht: Sind ja nur "soft"-Threads. Welche Genauigkeit benötigst du denn?

Captain America
2005-09-23, 17:06:30
Danke Jungs, echt cool! :D Probiere es nacher mal mit nanoTime(), klingt am sinnigsten. Eine Granularität von 1 ms reicht auch dicke aus.

Shink: Genauigkeit... Öhm naja eigentlich reicht eine Sekunde, aber das Problem ist, wenn das Programm lange läuft (über Stunden und Tage), summieren sich die Abweichungen. Wär allerdings auch nicht so schlimm, solange es keine Zeitsprünge gibt, die das Raum-Zeit-Kontinuum zerstören könnten. :upara:

Ist aber nen geniales Timing, gerade wenn wir uns hier diese Frage stellen, kommt das *g*

X-D

HellHorse
2005-09-24, 01:54:26
Sind ja nur "soft"-Threads.
Was meinst du damit? Das sind echte, native, präemptive Hardwarethreads. NPTL-Threads auf Linux und Windows-Threads auf Windows.

Shink
2005-09-24, 16:16:33
Was meinst du damit? Das sind echte, native, präemptive Hardwarethreads. NPTL-Threads auf Linux und Windows-Threads auf Windows.
Öhm... ja, stimmt wohl. Green Threads werden schon lang nicht mehr in Windows/Linux verwendet... Hmm, mal nachdenken, was ich mir dabei gedacht hab...