2016-03-08 23 views
9

[Edit]: Dopo aver ottenuto risposta che ho capito la sua non specifiche per Java, la sua correlata al sistema operativo di pianificazione, nonché, in modo da aggiungere altri tagUn thread può dormire per meno di mezzo milli secondi in Java/Other language?

E 'possibile in Java per fare un sonno filo per un nano secondi.

Ovviamente dopo aver osservato la API di Thread in cui possiamo passare anche nano secondi nel metodo sleep, la risposta potrebbe essere sì.

Ma dubito dopo aver guardato l'attuazione/fonte del metodo di sonno in Thread class, che è:

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); 
} 

Ora, secondo la logica che sta aumentando millisecondi dai 1 se i nano secondi trascorsi è più che mezzo milli secondi. Ma questo mi sembra illogico, diciamo che ho scritto un codice in cui uno dei miei thread è in attesa di dire qualche 40000 nano seconds (in pratica, potrebbe non essere il caso) che è meno di mezzo milli secondi, il che significa che il mio thread non aspetterà affatto.

Qualcuno può commentare lo stesso e perché questo motivo è stato deciso di attendere per secondi milli anziché nano secondi?

Inoltre, cosa garantirebbe che il thread si attivi correttamente?

+0

Cosa garantirebbe che il thread si attivi correttamente? – biziclop

+0

@biziclop esattamente. Modificherò la mia domanda per aggiungere questo punto – Vishrant

+0

@dr_debug non duplicato, sto chiedendo perché questo disegno è stato scelto piuttosto che permettere al thread di dormire per nano secondi – Vishrant

risposta

9

È possibile utilizzare LockSupport's parkNanos

LockSupport.parkNanos(400_000); 

tuttavia questo non è lo stesso di sonno (non è interrompibile) e tutto ciò che fa è passare la richiesta al sistema operativo. Su Windows 8, ad esempio, anche parkNanos(1) potrebbe dormire per 1 milli-secondo.

Come biziclop sottolineato, ci Javadoc menzioni

La chiamata spurio (cioè, per nessun motivo) ritorni.

Questo accade raramente nella mia esperienza, ma succede.


Tuttavia, hai ragione che Thread.sleep() dormirà sempre per almeno 1 ms. Su Win XP potrebbe dormire per 16 ms (1/60 di secondo)

Inoltre, cosa garantirebbe che il thread si attivi correttamente?

Utilizzo di un sistema operativo in tempo reale.

Quello che faccio è non andare a dormire ma piuttosto aspettare. In questo modo posso fermarmi per una quantità di tempo con maggiore precisione.Se si esegue il thread su una CPU isolato (in Linux) è possibile ridurre la variazione di circa 10 micro-secondi

Un esempio di occupati in attesa

long end = System.nanoTime() + delay; 
while (System.nanoTime() < end) { /* busy waiting */ } 

o se si vuole essere un po 'più amichevole

while (System.nanoTime() < end) 
    Thread.yield(); 
+0

@jtahlborn Non sono sicuro che tu intenda. È una classe integrata chiamata 'LockSupport' con un metodo' parkNanos' Ho aggiunto un Javadoc. –

+2

Mi piace particolarmente il fatto che ammettano che 'parkNanos()' possa tornare prima del tempo senza un motivo apparente. – biziclop

+0

@Peter Lawrey 'Su Win XP potrebbe dormire per 16 ms (1/60 di secondo)' Perché è così, è basato su come funziona il sistema operativo? E c'è comunque possiamo ridurlo al di sotto dei 16ms? Ho postato una domanda simile mesi fa, nessuno è stato in grado di rispondere .. – user3437460