Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using new Date() as unique identifier

Imagine i have a proccess that creates 1000 entities each second. for each of these entities i call the setter :

newEntity.setDate(new Date());

1) Is it possible that 2 entities will recieve the same date? or is it safe to assume that i do get a unique identifier effect for the date field?

2) If the answer to question #1 is :"yes" - let's make a minor tweak: lets create a function:

public static synchronized Date getDate() {
     return new Date();
}

will it work now?

newEntity.setDate(getDate());

3) what about

System.nanoTime()?

EDIT 4) what about :

public static synchronized Date getDate() {
     Thread.Sleep(1000);
     return new Date();
}

thanks.

like image 796
Urbanleg Avatar asked Dec 08 '22 13:12

Urbanleg


1 Answers

A simple test shows that two consecutive calls to new Date() can return the same date. Making the method synchronized won't make any difference.

If all you need is a unique ID, you could use an AtomicInteger counter and return counter.getAndIncrement(); for new ids.

ps: using System.nanotime() won't help either as the resolution is os and processor dependent and is generally low enough that two consecutive calls can return the same result too.


EDIT

Your 4th proposal to sleep for a second in a synchronized method would probably solve your unicity issue (although as pointed out by yshavit, nothing in the javadoc guarantees it). Note however that using a Date as a unique id is a bad idea in itself: Dates are mutable so the calling code could change its id with the setTime method (by mistake or on purpose).

Finally, if you really want your id to be date related, you could use a long representing milliseconds since the epoch and keep track of the existing ids - something like this:

private static final Set<Long> usedIds = new HashSet<> ();
public static synchronized long getUniqueId() {
    long millis;
    do {
        millis = System.currentTimeMillis();
    } while (!usedIds.add(millis));
    return millis;
}
like image 85
assylias Avatar answered Dec 11 '22 04:12

assylias