Generazione di un identificatore univoco globale in Java

Riepilogo: Sto sviluppando un’applicazione web Java persistente e devo assicurarmi che tutte le risorse che persisto abbiano identificatori univoci globali per evitare duplicati.

La stampa fine:

  1. Non sto usando un RDBMS, quindi non ho alcun generatore di sequenze di fantasia (come quello fornito da Oracle)
  2. Mi piacerebbe che fosse veloce, preferibilmente tutto in memoria – preferirei non dover aprire un file e incrementare qualche valore
  3. Deve essere thread-safe (sto anticipando che solo una JVM alla volta dovrà generare ID)
  4. Deve esserci coerenza tra le istanze di JVM. Se il server si arresta e si avvia, il generatore di ID non dovrebbe rigenerare gli stessi ID generati nelle istanze precedenti (o almeno la possibilità deve essere davvero, molto sottile – prevedo molti milioni di risorse pre-esistenti)
  5. Ho visto gli esempi nell’articolo del modello ID univoco dell’EJB. Non funzioneranno per me (preferirei non affidarmi esclusivamente a System.currentTimeMillis () perché continueremo a persistere più risorse per millisecondo).
  6. Ho esaminato le risposte proposte in questa domanda . La mia preoccupazione per loro è, qual è la possibilità che otterrò un duplicato ID nel tempo? Sono incuriosito dal suggerimento di utilizzare java.util.UUID per un UUID , ma ancora una volta, le possibilità di un duplicato devono essere infinitamente piccole.
  7. Sto usando JDK6

Gli UUID piuttosto sicuri sono “abbastanza buoni”. Sono disponibili 340.282.366,920,938,463,463,374,607,431,770,000,000 UUID.

http://www.wilybeagle.com/guid_store/guid_explain.htm

“Per mettere questi numeri in prospettiva, il rischio annuale di essere colpiti da un meteorite è stimato in una possibilità su 17 miliardi, il che significa che la probabilità è di circa 0,00000000006 (6 × 10-11), equivalente alle probabilità di creare alcuni decine di trilioni di UUID in un anno e con un duplicato. In altre parole, solo dopo aver generato 1 miliardo di UUID al secondo per i prossimi 100 anni, la probabilità di creare un solo duplicato sarebbe di circa il 50%. essere circa il 50% se ogni persona al mondo possiede 600 milioni di UUID ”

http://en.wikipedia.org/wiki/Universally_Unique_Identifier

public class UniqueID { private static long startTime = System.currentTimeMillis(); private static long id; public static synchronized String getUniqueID() { return "id." + startTime + "." + id++; } } 

Se deve essere univoco per PC: potresti probabilmente usare (System.currentTimeMillis() << 4) | (staticCounter++ & 15) (System.currentTimeMillis() << 4) | (staticCounter++ & 15) o qualcosa del genere.

Ciò consentirebbe di generare 16 per ms. Se hai bisogno di più, sposta 5 e e con 31 ...

se deve essere univoco su più PC, è necessario combinare anche l'indirizzo MAC della scheda di rete principale.

modifica: per chiarire

 private static int staticCounter=0; private final int nBits=4; public long getUnique() { return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1); } 

e cambia nBits nella radice quadrata del numero più grande che dovresti generare per ms.

Finirà per rotolare. Probabilmente 20 anni o qualcosa con nBits a 4.

Dalla memoria i pacchetti remoti RMI contengono un generatore UUID. Non so se valga la pena indagare.

Quando ho dovuto generarli, in genere utilizzo un hash MD5 con l’ora corrente, il nome utente e l’indirizzo IP del computer. Fondamentalmente l’idea è di prendere tutto ciò che puoi scoprire sul computer / persona e poi generare un hash MD5 di queste informazioni.

Funziona molto bene ed è incredibilmente veloce (una volta che hai inizializzato MessageDigest per la prima volta).

perché non farlo così

 String id = Long.toString(System.currentTimeMillis()) + (new Random()).nextInt(1000) + (new Random()).nextInt(1000); 

se si desidera utilizzare un’implementazione più rapida e veloce che l’UUID java dia un’occhiata a:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/main/java/org/spf4j/concurrent/UIDGenerator.java

vedere le scelte e le limitazioni di implementazione in javadoc.

ecco un test unitario su come usare:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/test/java/org/spf4j/concurrent/UIDGeneratorTest.java