2014-12-25 16 views
15

In base al modello di memoria Java, è possibile riordinare le istruzioni purché l'esecuzione sia well-formed.Il riordino Java influisce su System.currentTimeMillis()?

Quindi mi chiedo, è possibile che i seguenti codici producano il seguente output?

[codici] [in uno stesso filo]

long a = System.currentTimeMillis(); 
long b = System.currentTimeMillis(); 
long c = System.currentTimeMillis(); 

[uscita]

a == 10, b == 20, c == 15 

Se non è possibile, allora ciò fa JVM/implementazioni fanno per evitare che ciò accada ?

+0

A meno che non si esegua questo su un sistema con l'orologio impostato molto vicino al 1 gennaio 1970, probabilmente non si otterranno quei valori esatti. Perché la JVM dovrebbe riordinare queste istruzioni? –

+0

@ElliottFrisch ciao. Questi valori esatti vengono usati per illustrare che a, b e c potrebbero non aumentare in modo monotono; non deve essere il 10, il 20 e il 15 :-P –

+0

@ElliottFrisch Ciò che mi interessa qui è la garanzia che questi 3 System.currentTimeMillis() non vengano riordinati dalla JVM? –

risposta

5

Si prega di vedere questa domanda Instruction reordering & happens-before relationship in java.

Credo che se non si è in una discussione diversa, l'esito di qualsiasi esecuzione sarà sempre coerente con l'ordine nel codice. In questa situazione, dal momento che è impossibile elaborarlo in ordine, dovrebbe essere buono anche se i tuoi campi sono visibili ad un altro thread.

+0

Joseph, grazie per la tua rapida risposta. Tuttavia, tendo a credere che queste 3 istruzioni possano essere eseguite fuori ordine, perché il richiamo di metodi non è un AZIONE definito dal modello di memoria Java, quindi non esiste alcuna relazione prima - per queste 3 istruzioni. Se int a = 1 + 1, int b = 2 + 2 in uno stesso thread può essere riordinato ed eseguito come int b = 2 + 2, int a = 1 + 1, allora qual è lo speciale di System.currentTimeMillis() che li fa essere eseguiti in ordine? –

+0

In pratica, 'currentTimeMillis' è considerato come" è una chiamata esterna, quindi non so cosa faccia e non lo ordinerò di nuovo ". Altrimenti supponiamo che il riordinatore sappia come funziona, se questo metodo fosse implementato puramente in java, dovrebbe leggere alcune variabili volatili (orologio di sistema). Ad ogni modo, non dovrebbe essere riordinato. – Sebi

+0

@Sebi, mi piace la tua inferenza; qualsiasi riferimento può provarlo? –

1

A causa di una chiamata di sistema dell'utente, i compilatori non devono riordinarli nello stesso thread. Se ciò non fosse vero, potremmo persino sperimentare effetti di riordino in System.out.println (valori indipendenti); Immagino che l'accesso all'orologio del Sistema/OS crei una sorta di relazione tra queste operazioni (sempre per il thread corrente), quindi in teoria esiste una sorta di dipendenza tra di loro. Probabilmente, JVM considera questo problema e non riordina mai le chiamate del sistema utente.

+0

Chi dice che currentTimeMillis è una chiamata di sistema? Questo è un dettaglio di implementazione. – usr

+0

Si tratta di un dettaglio di implementazione sì, ma in realtà l'implementazione corrente non utilizza le risorse di sistema? Se sì, questo può essere censurato da JVM ed evita il riordino. Se l'implementazione predefinita non include una chiamata di sistema, le cose potrebbero essere diverse. –

+0

Stai dicendo che le chiamate al metodo "nativo" non possono essere riordinate? –