Reputation: 4362
What's the possibility of below code generating same last 7 digits when called successively from one thread?
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
String temp = String.valueOf(System.currentTimeMillis());
return new BigInteger(temp).add(BigInteger.valueOf(new Long(activityIdCounter.incrementAndGet())));
activityIdCounter
is AtomicInteger
and above snippet is static
synchronized
.
I am asking this because I have found intermittently my test cases have failed due to existing id being reused. And this is a part of getting the unique ids.
Right now, I have changed to System.nanoTime()
but I am not sure how
Let me explain briefly how this generateId()
method is called.
Tests classes call it twice sequentially for each call to DB for generating two different ids and both ids are persisted. Any other call or test method, will also do same. But for the operation to succeed in DB, this ids will be searched if they exist already in DB as ...where id1=:id1 and id2=:id2
.
Now here is my TestNG configuration:
<test verbose="2" name="FullTestSuite" annotations="JDK" preserve-order="true" parallel="classes" thread-count="10">
Edit: id creation logic
id1 = new BigInteger(<12-13 digits - constant>).add(<generated id>).toString();
id2 = "someString:" + id1 + ":" + generatedId; //call again for those 7 digits
Upvotes: 0
Views: 92
Reputation: 11308
If you only use 7 digits you have 10 000 000 possible different values. Assuming you picked numbers completely random over that range, then after picking 3723 numbers, the odds of generating a duplicate are greater than 50%. And after 6785 picks, odds for generating a duplicate are over 90%.
Of course you don't pick them randomly, you try to make them increase. But if you only pick the last seven digits, then purely time based, you have an overflow after 10 000 000 milliseconds, or once every 2 hours, 46 minutes, and 40 seconds. And since you add an ever increasing number to the millis, that period will get shorter and shorter.
Also note that since you use System.currentTimeMillis()
, you are exposed to changes in the system clock by other processes, most notably processes that do NTP sync. This means that two successive calls to System.currentTimeMillis()
may see a lower value on the second call.
Conclusion : to safely generate unique ids, you'll have to use way more digits. In fact don't reinvent the wheel, use UUID.randomUUID()
.
Upvotes: 1