# Thread weniger als 1 Millisekunde Schlafen legen



## outbreaker (23. Mai 2007)

Hallo

Ich schreibe ein Netzwerktool was in bestimmten Zeitabständen Datenpakete abschicken soll. Nun habe ich das Problem das ich mit Thread.sleep() meinen Thread mindestens eine Millisekunde schlafen lassen muss. Daduch kann ich maximal 6Mbit Datenrate bei UDP erreichen wenn ich den Sleep weglasse komme ich auf min 70 Mbit. 
Nun ist meine Frage ob es eine Möglichkeit gibt den Thread weniger als eine Milliskeunde Schlafen zu lassen?
also so im Mikrosekundenbereich?
Hat jemand eine idee? oder schon mal was eigene geschrieben was das kann?

danke


----------



## Wildcard (23. Mai 2007)

outbreaker hat gesagt.:
			
		

> Nun ist meine Frage ob es eine Möglichkeit gibt den Thread weniger als eine Milliskeunde Schlafen zu lassen?
> also so im Mikrosekundenbereich?


Nein, und es gibt auch keine Möglichkeit einen Thread eine Millisekunde schlafen zu lassen.
Es gibt zwar diese Methode:
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#sleep(long, int)
aber das ist von der Auflösung des Betriebssystems abhängig, unter einer Millisekunde wirst du nicht schaffen.
Altenativ ist noch Thread.yield() zu nennen.


----------



## The_S (23. Mai 2007)

Ne, geht nicht. Generell solltest du darauf verzichten einen Thread weniger als 20 Millisekunden schlafen zu legen, ansonsten kann es zu Problemen kommen!


----------



## byte (23. Mai 2007)

Mit Java SE 5+ geht (theoretisch) folgendes:


```
TimeUnit.NANOSECONDS.sleep(...);
```


----------



## outbreaker (23. Mai 2007)

Das funktioniert leider nicht:



			
				byto hat gesagt.:
			
		

> Mit Java SE 5+ geht (theoretisch) folgendes:
> 
> 
> ```
> ...



Es gibt zwar keinen Fehler aber einen sleep macht er auch nicht. Es gibt keinen Unterschied ob ich das implementiere oder die Zeile weglasse

hab es zum Testen mal mit 


```
TimeUnit.MICROSECONDS.sleep(1000)
```

gemacht
dann hat er wieder eine Milliskeunde pausiert wie bei Thread.sleep()
wenn ich weniger als 1000 genommen habe dann sleep er auch 1ms und nicht weniger

alles nen bissle komisch


gibt es vielleicht andere JNI - Klassen die man nutzen könnte?


----------



## KSG9|sebastian (23. Mai 2007)

So wie ich das sehe kannst du da zwar Microseconds angeben, jedoch ist der kleinste Wert 1MS (was ich auf die schnelle im JAD gesehen hab werden die Microsecs in Millis umgewandelt...


----------



## outbreaker (23. Mai 2007)

ich habe mir mal in openjava die Sleepmethode angesehen und die sieht so aus:

```
public static void sleep(long millis, int nanos) throws InterruptedException {
	if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
	}

	if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
				"nanosecond timeout value out of range");
	}

	if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
	    millis++;
	}

	sleep(millis);
}
```

da wird auch alles in millis umgerechnet

und die sleep(millis); is dann ne native methode


```
public static native void sleep(long millis) throws InterruptedException;
```

wenn ich den code finden würde könnte ich mir vielleicht ne eigne etwas abgewandelte sleep methode schreiben


----------



## hupfdule (23. Mai 2007)

outbreaker hat gesagt.:
			
		

> wenn ich den code finden würde könnte ich mir vielleicht ne eigne etwas abgewandelte sleep methode schreiben


Eher nicht. Denn du musst ja im Endeffekt das Betriebssystem veranlassen zu warten. Und Betriebssysteme sind i.d.R. nicht genauer als 10ms.
Du wirst es also auch nicht umschreiben können.


----------



## outbreaker (23. Mai 2007)

das is ärgerlich

es muss doch möglich seine eine Methode alle 0,5ms auszuführen und nicht nur alle 1ms


----------



## byte (23. Mai 2007)

Versuchs mal mit einem Echtzeitbetriebssystem, das diese Genauigkeit bietet.


----------



## hupfdule (23. Mai 2007)

outbreaker hat gesagt.:
			
		

> es muss doch möglich seine eine Methode alle 0,5ms auszuführen und nicht nur alle 1ms


Dein Programm ist nicht das einzige im System. Das Betriebssystem teil allen Prozessen eine gewisse Rechenzeit zu. Und es ist dem Betriebssystem einfach nicht möglich, dir so hoch aufgelöst die Rechenzeit zuzuweisen. Das ist in anderen Sprachen auch nicht so.

Könnte maximal bei einem Echtzeitbetriebssystem funktionieren, wobei ich auch nicht glaube, dass die auf 0,5ms genau sind.


----------



## Wildcard (23. Mai 2007)

outbreaker hat gesagt.:
			
		

> es muss doch möglich seine eine Methode alle 0,5ms auszuführen und nicht nur alle 1ms


Das dein Thread wirklich nur eine Millisekunde schläft darf bezweifelt werden.


----------



## outbreaker (23. Mai 2007)

is ja richtig das er nicht nur eine ms schläft is schon klar aber er kommt relaiv gleichmäßig dran und kann arbeiten

das is ja das was ich erreichen will

und das mein Programm nich das einzige ist ist auch richtig aber ich versuche nichts weiter auf dem Testrechner laufen zu lassen außer ein ganz einfaches Linux welches dieses Programm ausführen soll


----------



## hupfdule (23. Mai 2007)

outbreaker hat gesagt.:
			
		

> is ja richtig das er nicht nur eine ms schläft is schon klar aber er kommt relaiv gleichmäßig dran und kann arbeiten
> 
> das is ja das was ich erreichen will


Wenn es dir nur um _Gleichmäßigkeit_ geht, warum reichen dir dann nicht 10 oder 20ms?



> und das mein Programm nich das einzige ist ist auch richtig aber ich versuche nichts weiter auf dem Testrechner laufen zu lassen außer ein ganz einfaches Linux welches dieses Programm ausführen soll


Dann gib dort mal 
	
	
	
	





```
ps aux
```
 ein. Dann siehst du, was da noch so alles läuft. ;-)


----------



## Wildcard (23. Mai 2007)

outbreaker hat gesagt.:
			
		

> is ja richtig das er nicht nur eine ms schläft is schon klar aber er kommt relaiv gleichmäßig dran und kann arbeiten
> 
> das is ja das was ich erreichen will


Dann nimm wie oben erwähnt yield. Dann kommt dein Programm nicht in immer gleichen Abständen dran, aber es kann arbeiten und braucht nicht die ganze CPU.


----------



## outbreaker (23. Mai 2007)

ich weiß das da noch Prozesse laufen aber das sind sehr wenige und die brauchen nur sehr wenig Rechenzeit

Die meiste steht für mein Programm zur Verfügung


----------



## madboy (23. Mai 2007)

hupfdule hat gesagt.:
			
		

> Und es ist dem Betriebssystem einfach nicht möglich, dir so hoch aufgelöst die Rechenzeit zuzuweisen. Das ist in anderen Sprachen auch nicht so.





			
				outbreaker hat gesagt.:
			
		

> ein ganz einfaches Linux welches dieses Programm ausführen soll


Unter Linux (seit Kernel 2.6.x, weiß ich jetzt grad nicht genau ab wann) läuft der System-Timer mit 1000 HZ => macht 1 ms.

Wenn du dir nen neuen Kernel bauen willst, kannst das allerdings hier einstellen:
linux-source-2.6.20/include/asm-*/param.h:# define HZ
* = verwendete Architektur
Ob das allerdings dann auch irgendwie durch die Java VM durchgereicht werden kann weiß ich nicht.

Die Alternative wäre natürlich (wie schon von byto und hupfdule gepostet) ein RT-Linux. Ob mit Java Realzeit möglich ist wage ich allerdings zu bezweifeln.

Das einfachste wäre natürlich immer noch die von Wildcard empfohlene Methode oder active waiting wie ich in Thread http://www.java-forum.org/de/viewtopic.php?t=49630 geschrieben habe. Wenn sowieso nur deine Anwendung auf dem Rechner läuft sollte es ja egal sein wenn der Prozessor zu 100% ausgelastet ist. 
Auch wenn mehrere Threads parallel zählen sollte das funktionieren, so lange die Threads relativ lange leben (zumindest in der Theorie :wink: ), da ja ständig nachgeregelt wird.

Gruß,
madboy


----------



## Wildcard (23. Mai 2007)

madboy hat gesagt.:
			
		

> Die Alternative wäre natürlich (wie schon von byto und hupfdule gepostet) ein RT-Linux. Ob mit Java Realzeit möglich ist wage ich allerdings zu bezweifeln.


http://java.sun.com/javase/technologies/realtime/index.jsp


----------



## madboy (23. Mai 2007)

Aber man lernt ja bekanntlich nie aus :wink:


----------

