如何在Java中创建一个64位的唯一的整数

问题描述 投票:2回答:4

我需要在Java中创建一个64位的唯一的整数,这样的碰撞几率低。该系统是不是分布式的,所以不同的计算机之间的碰撞是没有问题的。

有什么办法,我们可以在Java中创建一个64位整数,它始终是唯一的?

截至目前我使用 -

long number = System.nanoTime();

这是产生64位唯一的整数正确的方式在Java或者是还有什么我能试试吗?

更新: -

如何做这个呢?这会不会是唯一的?

UUID number = UUID.randomUUID();
long uniqueNumber = number.timestamp();
java random 64bit long-integer uuid
4个回答
5
投票

如果您需要的号码是唯一的一个过程,重新启动之间强大的,你可以使用一个简单的AtomicLong和计时器。

private static final AtomicLong TS = new AtomicLong();
public static long getUniqueTimestamp() {
    long micros = System.currentTimeMillis() * 1000;
    for ( ; ; ) {
        long value = TS.get();
        if (micros <= value)
            micros = value + 1;
        if (TS.compareAndSet(value, micros))
            return micros;
    }
}

这会给你一个独特的“时间戳”以毫秒精度,但只能处理每毫秒1000个IDS没有走在前面的实际时间。这工作正常,在重新启动的时候会跳过去之前的值(再次假设你有每秒平均不到一百万)


3
投票

使用HashSet,以确保您存储值的唯一性。然后,您可以检查是否插入是通过检查add返回什么成功。如果值必须是“随机”你可以使用自己的算法,入住或退房手续SecureRandom

Long getUniqueNumber(HashSet uniqueNumberSet) {
    Long unique = generateUniqueNumber();
    if(!uniqueNumberSet.add(unique)) { // handle collision }
    return unique;
}

1
投票

作为Marc B说,最好的办法是简单long它初始化为零,每递增你需要一个新的价值的时间。

如果你需要的并发,或如果性能是不是一个问题的话,那么你可以使用AtomicLong通过Loc Ha的建议;但是,如果你真的需要它是一个长期的,而不是一个int,那么我怀疑你将要产生大量的人,所以你应该避免AtomicLong的额外开销,除非你确信你还需要并发。

System.nanoTime()是不是一个好主意,因为你不能保证它连续两次调用总是产生不同的值。

编辑(覆盖问题更新)

不,UUID的时间戳部分是不能保证是唯一的,正是相同的原因,System.nanoTime()不能保证是唯一的。如果UUID的时间戳是独一无二的,那么就没有必要有一个UUID类型,我们只是始终使用时间戳的一部分。时间总是一个坏的方式去保证唯一性。


0
投票

你想获得唯一的ID,用适当的方式(尽管128位):

UUID.randomUUID();

少一点适当(碰撞*是可能的)64位:

UUID.getLeastSignificantBits();
UUID.getMostSignificantBits();

要真正获得唯一的ID(如果他们是你的操作至关重要):

  1. 使用所有标识的集中存储
  2. 当你需要一个ID,让这个集中式系统处理它 - > DB和自动递增的值通常是最简单的方法

*碰撞=> 2个或更多相等的值

© www.soinside.com 2019 - 2024. All rights reserved.