4
\$\begingroup\$

I need to generate a 64 bit unique integer in Java. I need to make sure that there is very few or no collisions if possible.

I came up with the below code which works fine:

public class TestUniqueness {
 private static final AtomicLong TS = new AtomicLong();
 public static void main(String[] args) {
 // for testing, just added the for loop
 for (int i = 1; i <= 100000; i++) {
 System.out.println(getUniqueTimestamp());
 }
 }
 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;
 }
 }
}

I will be running the above code in production.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Feb 6, 2015 at 21:42
\$\endgroup\$
5
  • 1
    \$\begingroup\$ What do you mean by a "unique" integer? \$\endgroup\$ Commented Feb 6, 2015 at 23:10
  • \$\begingroup\$ This is tagged random but you are just getting the current time without repeats, which doesn't qualify as random in my book. \$\endgroup\$ Commented Feb 7, 2015 at 0:02
  • 3
    \$\begingroup\$ In short, what are your specifications, and how does a simple incrementing counter not satisfy them? \$\endgroup\$ Commented Feb 7, 2015 at 0:03
  • \$\begingroup\$ @PierreMenard My specification is only to generate the 64 bit unique integer, that's it. If it is random, then that is also fine. \$\endgroup\$ Commented Feb 7, 2015 at 0:06
  • 1
    \$\begingroup\$ System.nanoTime() (Don't see relation to tag random) \$\endgroup\$ Commented Jan 10, 2016 at 7:05

3 Answers 3

12
\$\begingroup\$

My specification is only to generate the 64 bit unique integer, that's it.

In this case, there's no need for anything more complicated than atomically incrementing a counter:

public class Counter {
 private static final AtomicLong counter = new AtomicLong(0);
 public static long getNextNumber(){
 return counter.incrementAndGet();
 }
}

To offer a more specific critique of your code, it's unnecessarily complicated and inefficient. I don't see anything incorrect about it (i.e. it seems like it meets your criteria), but there's the old saying about obviously no bugs vs no obvious bugs (paraphrased).

answered Feb 9, 2015 at 16:40
\$\endgroup\$
2
  • \$\begingroup\$ If this is a code that runs in a server that can go down and needs to be restarted, then I think that it would be good to set the initial time of AtomicLong to the current system time. In that way, when the server is restarted, it does not even repeat on values that it generated before being restarted. \$\endgroup\$ Commented Sep 15, 2015 at 17:18
  • 1
    \$\begingroup\$ @JadieldeArmas That won't work, you will get conflicts eventually. If you're incrementing from a timestamp, and then restart in the future, the new starting timestamp has a chance of being a number you previously used. It's much better to lookup the last max value and then restart from there. \$\endgroup\$ Commented Jan 10, 2017 at 21:48
3
\$\begingroup\$

Just some points:

for (;;) {
 long value = TS.get();
 if (micros <= value)
 micros = value + 1;
 if (TS.compareAndSet(value, micros))
 return micros;
}

Here, I suggest you do while(true) instead of for(;;). It is a matter of preference, but I think while(true) is easier to understand.


Also, always put braces for if statements. If you don't, horrible bugs may occur. Here is an example:

Say you have this if statement:

if(isSomething())
 doSomething();

And then you decide that the code has to do something else in the if statement:

if(isSomething())
 doSomething();
 doSomethingElse();

Now you have a horrible bug. It looks fine, but when you run it, doSomethingElse() will execute no matter what isSomething() returns. If you actually had braces:

if(isSomething()) {
 doSomething();
}

Then:

if(isSomething()) {
 doSomething();
 doSomethingElse();
}

That should work fine.

answered Feb 6, 2015 at 22:38
\$\endgroup\$
1
\$\begingroup\$

Is there any reason why you are not using the Apache library?

The RandomStringsUtils library provides a method for creating a random number.

The best part: you specify the range.

Library

By the way, the method is randomNumber()

SirPython
13.4k3 gold badges38 silver badges93 bronze badges
answered Feb 6, 2015 at 21:57
\$\endgroup\$
1
  • \$\begingroup\$ Looks ok, but I need to have uniqueness. Random doesn't mean unique. \$\endgroup\$ Commented Feb 6, 2015 at 22:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.