Генерация глобального уникального идентификатора в Java - PullRequest
12 голосов
/ 11 октября 2008

Резюме: Я занимаюсь разработкой постоянного веб-приложения на Java, и мне нужно убедиться, что все сохраняемые ресурсы имеют глобально уникальные идентификаторы для предотвращения дублирования.

Шрифт:

  1. Я не использую СУБД, поэтому у меня нет никаких причудливых генераторов последовательностей (например, предоставляемых Oracle)
  2. Я бы хотел, чтобы это было быстро, желательно все в памяти - я бы предпочел не открывать файл и увеличивать какое-то значение
  3. Это должно быть поточно-ориентированным (я ожидаю, что только одна JVM за раз должна будет генерировать идентификаторы)
  4. Должна быть согласованность между экземплярами JVM. Если сервер выключается и запускается, генератор идентификаторов не должен заново генерировать идентичные идентификаторы, которые он генерировал в предыдущих экземплярах (или, по крайней мере, шанс должен быть очень, очень небольшим - я ожидаю, что миллионы ресурсов будут сохранены)
  5. Я видел примеры в статье шаблона уникального идентификатора EJB. Они не будут работать для меня (я бы предпочел не полагаться исключительно на System.currentTimeMillis (), потому что мы будем сохранять несколько ресурсов в миллисекунду).
  6. Я посмотрел на ответы, предложенные в на этот вопрос . Я беспокоюсь о них, какова вероятность того, что со временем я получу дубликат ID? Я заинтригован предложением использовать java.util.UUID для UUID , но опять же, вероятность дублирования должна быть бесконечно мала.
  7. Я использую JDK6

Ответы [ 6 ]

31 голосов
/ 11 октября 2008

Довольно уверен, что UUID "достаточно хороши". Доступно 340 282 366 920 938 463 463 374 607 431 770 000 000 UUID.

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

"Чтобы представить эти цифры в перспективе, ежегодный риск удара метеоритом оценивается в один шанс из 17 миллиардов, что означает, что вероятность составляет около 0,00000000006 (6 × 10−11), что эквивалентно вероятности создание нескольких десятков триллионов UUID в год и создание одного дубликата. Другими словами, только после генерирования 1 миллиарда UUID каждую секунду в течение следующих 100 лет вероятность создания только одного дубликата составит около 50%. один дубликат будет составлять около 50%, если каждый человек на земле будет иметь 600 миллионов единиц UUID "

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

1 голос
/ 13 октября 2008
public class UniqueID {
    private static long startTime = System.currentTimeMillis();
    private static long id;

    public static synchronized String getUniqueID() {
        return "id." + startTime + "." + id++;
    }
}
1 голос
/ 11 октября 2008

Если он должен быть уникальным для ПК: вы, вероятно, можете использовать (System.currentTimeMillis() << 4) | (staticCounter++ & 15) или что-то в этом роде.

Это позволит вам генерировать 16 в мс. Если вам нужно больше, сдвиньте на 5, и это с 31 ...

если он должен быть уникальным для нескольких компьютеров, вам также следует объединить MAC-адрес вашей основной сетевой карты.

изменить: уточнить

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

и измените nBits на квадратный корень из наибольшего числа, которое вам нужно сгенерировать за мс.

Это в конце концов перевернется. Вероятно, 20 лет или что-то с nBits на 4.

0 голосов
/ 30 сентября 2014

, если вы хотите использовать более короткую и быструю реализацию, которую java UUID взглянет на:

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

см. Варианты реализации и ограничения в javadoc.

Вот модульный тест по использованию:

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

0 голосов
/ 17 марта 2012

почему бы не сделать так

String id = Long.toString(System.currentTimeMillis()) + 
    (new Random()).nextInt(1000) + 
    (new Random()).nextInt(1000);
0 голосов
/ 13 октября 2008

Из памяти удаленные пакеты RMI содержат генератор UUID. Я не знаю, стоит ли это изучать.

Когда мне нужно было их сгенерировать, я обычно использую хэш-сумму MD5 текущей даты, имени пользователя и IP-адреса компьютера. По сути, идея состоит в том, чтобы взять все, что вы можете узнать о компьютере / человеке, а затем сгенерировать MD5-хэш этой информации.

Он работает очень хорошо и невероятно быстро (как только вы впервые инициализируете MessageDigest).

...