Java:如何提供独特的ID并重用它们?

时间:2014-06-24 16:47:36

标签: java unique identifier reusability finalize

我正在实现一个简单的类,用于为某些对象提供id:

class idObject
{
  private static long next=0;
  private long id;

  idObject()
  {
     id=next;
     next = next +1;
  }

}

并从中派生出我需要我的id的所有类。程序运行很长时间,并创建了很多对象。因此,我担心接下来可能会超越。这导致非唯一ID。有些对象活得很长,但大多数都会在某些时候被删除。但是,我想保持ID独特。

我的问题是,是否有一种简单的方法可以重复使用被删除对象的ID?我的想法是创建一个免费ID列表,并在它死亡时添加一个对象的id。最初,我是一名C ++程序员,所以我想过使用destructer,这显然不是Java中的。在这种情况下,finalize()方法是正确的选择吗?

最好的问候

5 个答案:

答案 0 :(得分:2)

如果您担心ID用完,可以使用UUID。存在16 ^ 32种可能的UUID组合并且是随机生成的。如果您想完全确定没有与现有ID冲突,您可以随时保留已创建的ID的注册表,并确保它不存在。

答案 1 :(得分:2)

UUID外,您还可以使用BigInteger。使用BigInteger,您可以获得顺序ID。

答案 2 :(得分:2)

可能最好的解决方案是UUID类(由其他人提及),但它是随机生成的,因此它可能不是唯一的,您将不得不通过保留已存在的ID列表来浪费内存。因此,如果你想确定id是唯一的,不会溢出而你不浪费内存,你可能想要使用BigInteger类。

你应该记住,如果有多个线程创建对象,你需要同步生成id的代码,所以你可能需要这样的东西:

class idObject
{
  private static BigInteger nextId = BigInteger.ZERO;
  private BigInteger id;

  private static synchronized BigInteger nextId() {
      BigInteger id = nextId;
      nextId = id.plus(BigInteger.ONE);
      return id;
  }

  idObject()
  {
     id = nextId();
  }

}

答案 3 :(得分:2)

通过简单地增加1来溢出一个长期将是一个相当大的壮举。快速CPU可能会在大约一秒钟内溢出一个int。

溢出长时间需要40亿倍的增量 - 目前至少需要40亿秒。由于只有大约3000万秒,所以你的程序需要大约133年的时间才能完成超长时间。

如果id是内存中对象的临时id,那么long就足够了。

答案 4 :(得分:1)

每秒分配1,000,000个对象,在公元586,540年左右的某个时间,您将使用唯一的64位标识符。除非你需要在某个地方保留这些标识符,因此它们在进程之间是唯一的,我认为你可以安全地使用long

使用您的代码轻微狡辩:您的idObject()方法不是线程安全的,并且如果一次从不同的线程调用,则可以返回重复的ID。在这种情况下,我建议使用AtomicLong来存储ID。