Domanda

Riepilogo: sto sviluppando un'applicazione Web Java persistente e devo assicurarmi che tutte le risorse che persisto abbiano identificatori univoci a livello globale per evitare duplicati.

La stampa fine:

  1. Non sto usando un RDBMS, quindi non ho generatori di sequenze fantasiose (come quello fornito da Oracle)
  2. Vorrei che fosse veloce, preferibilmente tutto in memoria - Preferirei non dover aprire un file e aumentare un po 'di valore
  3. Deve essere thread-safe (sto anticipando che solo una JVM alla volta dovrà generare ID)
  4. Deve esserci coerenza tra le istanze della JVM. Se il server si arresta e si avvia, il generatore di ID non dovrebbe rigenerare gli stessi ID che ha generato nelle precedenti istanze (o almeno la possibilità deve essere davvero, molto sottile - prevedo molti milioni di risorse preesistenti)
  5. Ho visto gli esempi nell'articolo modello ID univoco EJB. Non funzioneranno per me (preferirei non fare affidamento esclusivamente su System.currentTimeMillis () perché persisteremo risorse multiple per millisecondo).
  6. Ho esaminato le risposte proposte in questo domanda . La mia preoccupazione per loro è: qual è la possibilità che ottengo un ID duplicato nel tempo? Sono incuriosito dal suggerimento di utilizzare java .util.UUID per un UUID , ma ancora una volta, le possibilità di un duplicato deve essere infinitamente piccolo.
  7. Sto usando JDK6
È stato utile?

Soluzione

Gli UUID abbastanza sicuri sono " abbastanza buono " ;. Ci sono 340.282.366.920.938.463.463.374.607.431.770.000.000 UUID disponibili.

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

" Per mettere in prospettiva questi numeri, si stima che il rischio annuale di essere colpiti da un meteorite sia una possibilità su 17 miliardi, il che significa che la probabilità è di circa 0,00000000006 (6 & # 215; 10 & # 8722; 11), equivalente alla probabilità di creare alcune decine di trilioni di UUID in un anno e di avere un duplicato. In altre parole, solo dopo aver generato 1 miliardo di UUID ogni secondo per i prossimi 100 anni, la probabilità di creare un solo duplicato sarebbe di circa il 50%. La probabilità di un duplicato sarebbe di circa il 50% se ogni persona sulla terra possiede 600 milioni di UUID & Quot;

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

Altri suggerimenti

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: probabilmente potresti utilizzare (System.currentTimeMillis() << 4) | (staticCounter++ & 15) o qualcosa del genere.

Ciò ti consentirebbe di generare 16 per ms. Se hai bisogno di più, sposta di 5 e poi 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 modifica nBits nella radice quadrata del numero più grande che dovresti generare per ms.

Alla fine passerà sopra. Probabilmente 20 anni o qualcosa del genere con nBits a 4.

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

Quando ho dovuto generarli, di solito utilizzo un hashsum MD5 della data e ora correnti, il nome utente e l'indirizzo IP del computer. Fondamentalmente l'idea è quella di prendere tutto ciò che puoi scoprire sul computer / persona e quindi generare un hash MD5 di queste informazioni.

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

perché non fare così

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

se si desidera utilizzare un'implementazione più breve e più veloce a cui l'UUID java dà un'occhiata:

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

vedi le scelte e le limitazioni di implementazione nel 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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top