Question

Résumé: je développe une application Web Java persistante et je dois m'assurer que toutes les ressources que je conserve ont des identificateurs globaux uniques pour éviter les doublons.

L'impression fine:

  1. Je n'utilise pas de SGBDR, je n'ai donc aucun générateur de séquence fantaisie (tel que celui fourni par Oracle)
  2. J'aimerais qu'il soit rapide, de préférence tout en mémoire - je préfère ne pas avoir à ouvrir un fichier et à incrémenter une valeur
  3. Il doit être thread-safe (je pense qu’une seule machine virtuelle à la fois devra générer des identifiants)
  4. Il doit y avoir une cohérence entre les instanciations de la machine virtuelle Java. Si le serveur s'arrête et démarre, le générateur d'identifiants ne devrait pas générer à nouveau les identifiants qu'il avait générés lors d'instanciations précédentes (ou du moins, les chances doivent être vraiment minces - j'imagine des millions de ressources stockées)
  5. J'ai vu les exemples de l'article sur le modèle d'identification unique EJB. Ils ne fonctionneront pas pour moi (je préfère ne pas compter uniquement sur System.currentTimeMillis () car nous allons conserver plusieurs ressources par milliseconde).
  6. J'ai consulté les réponses proposées dans ceci question . Ma préoccupation à leur sujet est la suivante: quelles sont les chances pour que je reçoive un ID en double au fil du temps? Je suis intrigué par la suggestion d'utiliser java .util.UUID pour un UUID , mais encore une fois, les chances de duplication besoin d'être infiniment petit.
  7. J'utilise JDK6
Était-ce utile?

La solution

Assez sûr que les UUID sont & "assez bons &"; Il y a 340.282.366.920.938.463.463.374.607.431.770.000.000 UUID disponibles.

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

& "Pour mettre ces chiffres en perspective, le risque annuel d'être frappé par une météorite est estimé à une chance sur 17 milliards, ce qui signifie que la probabilité est d'environ 0,00000000006 (6 & # 215; 10 & # 8722; 11), ce qui équivaut à la probabilité de créer quelques dizaines de milliards de dollars d’UUID par an et d’avoir un doublon. En d’autres termes, ce n’est qu’après avoir généré 1 milliard d’UUID par seconde pour les 100 prochaines années que la probabilité de créer un seul duplicata serait d’environ 50%. La probabilité d’un duplicata serait d’environ 50% si chaque habitant de la Terre possédait 600 millions d’UUID & ";

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

Autres conseils

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

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

S'il doit être unique par PC: vous pouvez probablement utiliser (System.currentTimeMillis() << 4) | (staticCounter++ & 15) ou quelque chose du genre.

Cela vous permettrait de générer 16 par ms. Si vous avez besoin de plus, décalez-vous de 5 et puis 31 ...

si elle doit être unique sur plusieurs PC, vous devez également combiner l'adresse MAC de votre carte réseau principale.

modifier: pour clarifier

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

et remplacez nBits par la racine carrée du plus grand nombre à générer par ms.

Il finira par se retourner. Probablement 20 ans ou quelque chose avec nBits à 4.

De mémoire, les packages distants RMI contiennent un générateur d'UUID. Je ne sais pas si cela mérite d'être étudié.

Lorsque je dois les générer, j'utilise généralement un hashs MD5 indiquant l'heure, le nom d'utilisateur et l'adresse IP de l'ordinateur. En gros, l’idée est de prendre tout ce que vous pouvez trouver sur l’ordinateur / la personne, puis de générer un hachage MD5 de cette information.

Cela fonctionne vraiment bien et est incroyablement rapide (une fois que vous avez initialisé le MessageDigest pour la première fois).

pourquoi ne pas faire comme ça

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

si vous souhaitez utiliser une implémentation plus courte et plus rapide que java UUID, consultez:

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

voir les choix d'implémentation et les limites dans le javadoc.

voici un test unitaire sur la façon d'utiliser:

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top