Ho bisogno di creare un timestamp (in millisecondi) in Java che è garantito essere univoco in quella particolare istanza VM. Cioè è necessario un modo per limitare il throughput di System.currentTimeMillis() in modo che restituisca al massimo un risultato ogni ms. Qualche idea su come implementarlo?Creazione di un timestamp univoco in Java
risposta
Questo darà un tempo il più vicino possibile al tempo corrente senza duplicati.
private static final AtomicLong LAST_TIME_MS = new AtomicLong();
public static long uniqueCurrentTimeMS() {
long now = System.currentTimeMillis();
while(true) {
long lastTime = LAST_TIME_MS.get();
if (lastTime >= now)
now = lastTime+1;
if (LAST_TIME_MS.compareAndSet(lastTime, now))
return now;
}
}
Un modo per evitare la limitazione di un id al milli-secondo è quello di utilizzare un micro-secondo timestamp. cioè moltiplicare currentTimeMS per 1000. Ciò consentirà 1000 id per millisecondo.
Nota: se il tempo scorre indietro, ad es. A causa di una correzione NTP, il tempo progredisce a 1 milli-secondo per invocazione fino a quando il tempo non si avvicina. ;)
È possibile utilizzare System.nanoTime()
, che è il timer di sistema disponibile più preciso e dividerlo per milione per ottenere i millisecondi. Anche se non ci sono garanzie formali sulla frequenza con cui viene aggiornato, credo sia ragionevole presumere che aggiorni molto più (ordine/i di grandezza) frequentemente di una volta al millisecondo. Naturalmente, se crei timestamp interi di un intervallo inferiore a millisecondi, non possono essere tutti univoci.
Si noti che il valore assoluto nanoTime()
è arbitrario. Se si desidera il tempo assoluto, calibrarlo in qualche modo, cioè confrontarlo con currentTimeMillis()
all'avvio.
È possibile utilizzare System.nanoTime()
per una migliore precisione
Anche se ho provato qui sotto e ogni volta che si dà valori diversi, probabilmente non è garantito per essere unico per tutto il tempo.
public static void main(String[] args) {
long time1 = System.nanoTime();
long time2 = System.nanoTime();
long time3 = System.nanoTime();
System.out.println(time1);
System.out.println(time2);
System.out.println(time3);
}
Un altro modo è quello di utilizzare AtomicInteger
/AtomicLong
classi per numeri unici, se il tempo non è importante per voi e basta numero unico, questo probabilmente è una scelta btter.
nanoTime è monotono, ma non sempre unico. Puoi ottenere molti duplicati. per esempio. su Red Hat & Centos 5.x la risoluzione è micro-secondi, quindi ottieni molti valori ripetuti. –
Grazie per le informazioni. Ho indovinato che dipende dal sistema operativo e dalla macchina. – fmucar
Puoi usare nanoTime con un controllo diverso. (Simile alla mia soluzione) Il nanoTime è il tempo di attività in meno di secondi su molti sistemi. –
Potrebbe forse fare uso di java.util.UUID
ed è timestamp()
e clockSequence()
?
Method Summary
int clockSequence()
The clock sequence value associated with this UUID.
long timestamp()
The timestamp value associated with this UUID.
Maggiori dettagli qui: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html
Durante la ricerca di una soluzione mi sono imbattuto ULIB (Universally Unique lexicographically ordinabili Identifier) https://github.com/huxi/sulky/tree/master/sulky-ulid/
Non è una lunga, ma più corto quindi UUID.
A ULID:
- è compatibile con UUID/GUID di 1.21e + 24 ULIDs unici al millisecondo (1,208,925,819,614,629,174,706,176 per l'esattezza)
- lexicographically ordinabili
- Canonicamente codificate come una stringa di 26 caratteri, in contrapposizione all'UUID 36 carattere
- Utilizza base32 di Crockford per una migliore efficienza e leggibilità (5 bit per carattere)
- caso insensitive
- nessun carattere speciale (sicuro URL)
- 1. Creazione timestamp UTC in Javascript
- 2. Timestamp MySQL solo su creazione
- 3. Confrontare due timestamp in java
- 4. Creazione di un grafico in java
- 5. Creazione di un Makefile Java
- 6. Query MYSQL: ultimo timestamp + valore univoco degli ultimi 30 minuti
- 7. Come generare ID univoco in Java (intero)?
- 8. come ottengo un ID univoco per oggetto in Java?
- 9. Ottieni un ID file univoco in Windows con Java?
- 10. Java: ID univoco di 10 cifre
- 11. Creazione vincolo univoco più colonne in MySQL Workbench diagramma EER
- 12. Timestamp stringa per Calendar in Java?
- 13. Converti timestamp unix alla data in java
- 14. Conversione Integer timestamp in data java
- 15. Java Timestamp - Aggiunta di cinque minuti
- 16. Genera ID univoco
- 17. Ottieni identificatore univoco di una discussione in Java 1.4
- 18. Creazione di un generatore di "Chiave di attivazione" in JAVA
- 19. Creazione di un server java con riposo
- 20. Creazione di un collegamento simbolico con Java
- 21. Arrotondare un timestamp alla data più vicina
- 22. Creazione di un nuovo oggetto in classe astratta in Java
- 23. Creazione di un vincolo univoco su due colonne insieme in Ecto
- 24. Creazione di un plist utilizzando Java
- 25. Timestamp per creazione di righe e ultima modifica
- 26. Cassandra: genera un ID univoco?
- 27. Java: creazione di un flusso di lavoro in quarzo
- 28. Creazione di un elenco di coppie in java
- 29. Creazione di un file di proprietà in Java ed eclissi
- 30. Percorso di creazione Java
non sono sicuro di quello che vuoi dire * * limitazione currentTimeMillis() in modo che restituisca al massimo * * un risultato ev ery ms? Se desideri timestamp univoci, preferiresti garantire che restituisca un valore diverso ad ogni chiamata, giusto? –
Devono essere monotonicamente in aumento? Devono sopportare qualche relazione con il tempo * effettivo *? Devono essere univoci su più percorsi? –