Skip to content

Instantly share code, notes, and snippets.

@icella
Last active June 18, 2024 09:29
Show Gist options
  • Save icella/d4011b6808fc549c538c0310528d9e94 to your computer and use it in GitHub Desktop.
Save icella/d4011b6808fc549c538c0310528d9e94 to your computer and use it in GitHub Desktop.
Java – Ways to Generate Unique Ids in Java
/**
* The object creation time can be set to object’s identifier property.
* For this purpose, System.currentTimeMillis() can be used. However,
* two or more objects may be created in a single millisecond.
* In this case, these objects will have the same id which is unacceptable.
* One way to cope with this problem is to use System.nanoTime().
* Even if the nano time is the smallest interval we can use, it does not
* also guarantee the uniqueness. To provide unique time stamps,
* I got help from AtomicReference class as follows.
*/
import java.util.concurrent.atomic.AtomicReference;
public class CurrentTimeId {
private static AtomicReference<Long> currentTime =
new AtomicReference<>(System.currentTimeMillis());
public static Long nextId() {
return currentTime.accumulateAndGet(System.currentTimeMillis(),
(prev, next) -> next > prev ? next : prev + 1)
}
}
/**
* Note that accumulateAndGet method is available since Java 8.
* If you use earlier versions you can implement the following method.
*/
import java.util.concurrent.atomic.AtomicReference;
public class CurrentTimeId {
private static AtomicReference<Long> currentTime =
new AtomicReference<>(System.currentTimeMillis());
public static Long nextId() {
Long prev;
Long next = System.currentTimeMillis();
do {
prev = currentTime.get();
next = next > prev ? next : prev + 1;
} while (!currentTime.compareAndSet(prev, next));
return next;
}
}
/**
* The simplest way of id generation is to maintain an id counter.
* The counter is actually an integer (mostly a Java long) that is
* incremented at each generation.
*
* The IdCounter below, holds a counter and provides the synchronized
* nextId() method returning the next value of the counter.
* Synchronization is crucial to guard your counter against concurrent
* accesses in multithreaded applications.
*/
public class IdCounter {
private static long counter = 0;
public static synchronized long nextId() {
return ++counter;
}
}
/**
* With Java 1.5+, a better way is using atomics like AtomicLong which
* are already thread-safe in nature. So, you don’t need an explicit synchronization.
*/
import java.util.concurrent.atomic.AtomicLong;
public class AtomicIdCounter {
private static AtomicLong counter = new AtomicLong(0);
public static long nextId() {
return counter.incrementAndGet();
}
}
/**
* Instances of java.rmi.server.UID class generates serializable identifiers
* which are unique on the host they are produced. The host must meet two conditions for uniqueness:
*
* Reboot time must be greater than 1 millisecond
* Its system clock is never set backward
* next class generates a different UID string at each nextUID() call (sample UID: -61bdd364:14a9f9c3782:-8000).
*/
import java.rmi.server.UID;
public class UIDGenerator {
public static String nextUID() {
return new UID().toString()
}
}
/**
* Our previous solution, UID, generates unique strings on the host.
* They are not globally unique. So, two JVM instances may produce same UIDs.
* If you need universally unique identifiers you can use java.util.
* UUID (Universally Unique IDentifier) class.
*
* The nextUUID() method below generates a different UUID (or GUID) string at
* each call (sample UUID: 251baa74-dc82-4e46-ae58-d7479c06eff5)
*/
import java.util.UUID;
public class UUIDGenerator {
public static String nextUUID() {
return UUID.randomUUID().toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment