Im besten Fall signalisiert ein Ereignis, dass Daten bereit stehen und abgeholt werden können. Doch nicht immer gibt es eine solche API. Dann findet sich oft ein wiederholter Test auf eine Bedingung und wird diese wahr, stehen zum Beispiel Daten zum Abholen bereit. In Code sieht das so aus:
while ( ! daten_da ) ; datenVearbeiten();
Dieses aktive Warten, engl. busy waiting, oder auch spinning genannt, auf Daten (eng. polling) mithilfe einer spin-loop verschwendet so programmiert viel Rechenzeit. Eine Lösung ist mit dem bekannten sleep(…) eine Zeit von Millisekunden zu schlafen, wobei es schwierig ist, die richtige Anzahl an Schlafsekunden zu ermitteln. Zu kurz geschlafen heißt: noch einmal weiter pollen; zu lang geschlafen, heißt: es gibt eine unnötige Verzögerung.
Die Thread-Klasse bietet zwei weitere Methoden, um kooperative Threads zu programmieren: die Methode yield() und ab Java 9 onSpinWait(). Anders als bei sleep(…) gibt es hier keine Millisekunden anzugeben.
while ( ! daten_da ) Thread.onSpinWait(); datenVearbeiten();
class java.lang.Thread
implements Runnable
- static void onSpinWait()
Signalisiert der Laufzeitumgebung. das der Thread in einer spin-loop auf Daten wartet. Dieser Hinweis kann die JVM an den Prozessor weitegeben und die Laufzeit ist bei typischen Systemen besser als mit yield(). Neu in Java 9 im Zuge der Umsetzung der „JEP 285: Spin-Wait Hints“.[1] - static voidyield()
Der laufende Thread gibt freiwillig seine Rechenzeit ab, sodass er bezüglich seiner Priorität wieder in die Thread-Warteschlange des Systems einordnet wird. Einfach ausgedrückt, signalisiert yield() der Thread-Verwaltung: „Ich setze diese Runde aus und mache weiter, wenn ich das nächste Mal dran bin.“ Die Methode ist für Implementierungen der JVM nicht verbindlich. Die API-Dokumentation warnt eher von der Methode „It is rarely appropriate to use this method.”
[1] http://openjdk.java.net/jeps/285