Pregunta

Resumen: estoy desarrollando una aplicación web Java persistente, y necesito asegurarme de que todos los recursos que persisto tengan identificadores únicos a nivel mundial para evitar duplicados.

La letra pequeña:

  1. No estoy usando un RDBMS, por lo que no tengo ningún generador de secuencia sofisticado (como el proporcionado por Oracle)
  2. Me gustaría que fuera rápido, preferiblemente todo en memoria, prefiero no tener que abrir un archivo e incrementar algún valor
  3. Debe ser seguro para subprocesos (estoy anticipando que solo una JVM a la vez necesitará generar ID)
  4. Es necesario que haya coherencia entre las instancias de la JVM. Si el servidor se apaga y se inicia, el generador de ID no debería volver a generar las mismas ID que generó en instancias anteriores (o al menos la posibilidad debe ser muy, muy escasa; anticipo muchos millones de recursos existentes)
  5. He visto los ejemplos en el artículo de patrón de ID único de EJB. No funcionarán para mí (prefiero no confiar únicamente en System.currentTimeMillis () porque persistiremos en múltiples recursos por milisegundo).
  6. He visto las respuestas propuestas en esto pregunta . Mi preocupación sobre ellos es, ¿cuál es la posibilidad de que con el tiempo obtenga una identificación duplicada? Me intriga la sugerencia de usar java .util.UUID para un UUID , pero nuevamente, las posibilidades de un duplicado debe ser infinitesimalmente pequeño.
  7. Estoy usando JDK6
¿Fue útil?

Solución

Estoy bastante seguro de que los UUID son " suficientemente bueno " ;. Hay 340,282,366,920,938,463,463,374,607,431,770,000,000 de UUID disponibles.

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

" Para poner estos números en perspectiva, se estima que el riesgo anual de ser golpeado por un meteorito es una posibilidad en 17 mil millones, lo que significa que la probabilidad es de aproximadamente 0.00000000006 (6 & # 215; 10 & # 8722; 11), equivalente a las probabilidades de crear unas pocas decenas de billones de UUID en un año y tener un duplicado. En otras palabras, solo después de generar mil millones de UUID por segundo durante los próximos 100 años, la probabilidad de crear un solo duplicado sería de aproximadamente el 50%. La probabilidad de un duplicado sería de aproximadamente el 50% si cada persona en la tierra posee 600 millones de UUID & Quot;

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

Otros consejos

public class UniqueID {
    private static long startTime = System.currentTimeMillis();
    private static long id;

    public static synchronized String getUniqueID() {
        return "id." + startTime + "." + id++;
    }
}

Si necesita ser único por PC: probablemente podría usar (System.currentTimeMillis() << 4) | (staticCounter++ & 15) o algo así.

Eso le permitiría generar 16 por ms. Si necesita más, cambie por 5 y con 31 ...

si necesita ser único en varias PC, también debe combinar la dirección MAC de su tarjeta de red principal.

editar: para aclarar

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

y cambie nBits a la raíz cuadrada del número más grande que debería generar por ms.

Eventualmente se volcará. Probablemente 20 años o algo así con nBits a las 4.

De la memoria, los paquetes remotos RMI contienen un generador de UUID. No sé si vale la pena estudiarlo.

Cuando he tenido que generarlos, normalmente utilizo un hash MD5 de la fecha y hora actual, el nombre de usuario y la dirección IP de la computadora. Básicamente, la idea es tomar todo lo que pueda averiguar sobre la computadora / persona y luego generar un hash MD5 de esta información.

Funciona realmente bien y es increíblemente rápido (una vez que haya inicializado el MessageDigest por primera vez).

¿por qué no hacer esto?

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

si desea utilizar una implementación más corta y más rápida que el UUID de Java eche un vistazo:

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

vea las opciones y limitaciones de implementación en el javadoc.

aquí hay una prueba unitaria sobre cómo usar:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top