Pergunta

Resumo:. Estou desenvolvendo uma aplicação web persistente Java, e eu preciso ter certeza de que todos os recursos que persistem têm identificadores exclusivos globalmente para evitar duplicatas

O Fine Print:

  1. Não estou usando um RDBMS, então eu não tem nenhum geradores de seqüência de fantasia (como o fornecido pela Oracle)
  2. Eu gostaria que ele seja rápido, de preferência todos na memória - Eu prefiro não ter de abrir um arquivo e incremento de algum valor
  3. Ele precisa ser thread-safe (estou antecipando que apenas uma JVM em um momento será necessário gerar IDs)
  4. É preciso haver consistência entre instâncias da JVM. Se os fecha servidor para baixo e começa acima, o gerador de ID não deve voltar a gerar os mesmos IDs que gerou em instâncias anteriores (ou pelo menos a chance tem que ser muito, muito magro - Prevejo muitos milhões de recursos presisted)
  5. Eu vi os exemplos no artigo padrão ID EJB único. Eles não vai funcionar para mim (eu prefiro não depender exclusivamente dos System.currentTimeMillis () porque vamos estar persistindo vários recursos por milissegundo).
  6. Eu olhei as respostas propostas no este questionar . A minha preocupação sobre eles é, qual é a chance que eu vou conseguir um ID duplicado ao longo do tempo? Estou intrigado com a sugestão de usar java .util.UUID por UUID , mas novamente, as chances de uma duplicata necessidade de ser infinitamente pequeno.
  7. Eu estou usando JDK6
Foi útil?

Solução

UUIDs certeza bonitas são "suficientemente bom". Há 340,282,366,920,938,463,463,374,607,431,770,000,000 UUIDs disponível.

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

"Para colocar estes números em perspectiva, o risco anual de um de ser atingido por um meteorito é estimada para ser uma chance em 17 mil milhões, o que significa a probabilidade é de cerca de 0,00000000006 (6 × 10-11), equivalente às chances de criando algumas dezenas de trilhões de UUIDs em um ano e ter um duplicado. em outras palavras, somente depois de gerar 1 bilhão de UUIDs a cada segundo para os próximos 100 anos, a probabilidade de criar apenas uma duplicata seria cerca de 50%. a probabilidade de uma duplicata seria cerca de 50%, se cada pessoa na terra possui 600 milhões UUIDs "

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

Outras dicas

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

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

Se ele precisa ser único por PC:. Você provavelmente poderia usar (System.currentTimeMillis() << 4) | (staticCounter++ & 15) ou algo parecido

Isso permitiria que você para gerar 16 por ms. Se precisar de mais, turno por 5 e e-lo com 31 ...

se ele precisa ser exclusivo em vários PCs, você também deve combinar o endereço MAC da placa de rede primária.

Edit: Para esclarecer

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

e altere nBits à raiz quadrada do maior número, caso haja necessidade de gerar por ms.

Ele acabará por rolar. Provavelmente 20 anos ou algo com nBits a 4.

Da memória os pacotes remotos RMI conter um gerador de UUID. Eu não sei se isso é pena olhar em.

Quando eu tive para gerá-los Eu normalmente uso um hashsum MD5 do tempo data atual, o nome do usuário eo endereço IP do computador. Basicamente, a idéia é fazer tudo o que você pode descobrir mais sobre o computador / pessoa e, em seguida, gerar um hash MD5 desta informação.

Ele funciona muito bem e é incrivelmente rápido (uma vez que você inicializa o MessageDigest pela primeira vez).

Por que não fazer como este

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

Se você quiser usar um mais curto e mais rápido de implementação que java UUID dar uma olhada em:

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

ver as opções de implementação e limitações no javadoc.

aqui é um teste de unidade sobre como usar:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top