Class TimeIdGenerator

java.lang.Object
com.norconex.commons.lang.TimeIdGenerator

public final class TimeIdGenerator extends Object

Generates a unique ID made out of the current time in milliseconds, combined with a thread-safe atomic sequence value that guarantees order and uniqueness within the same JVM.

This class was created for cases where unique sequential IDs are required to be long primitives, or where long are desired for things such as faster lookup and generation (over large strings for instance) and you can't use a persistent sequence generator. If you do not have such need, it is best advised to use a universal id generator instead, like java UUID.

The fine-prints

At a minimum, values generated by this class ensures uniqueness within JVM instances (read Year 2262 and beyond further down). If you need larger or different values to ensure greater uniqueness between many JVMs, you can convert the returned value to a string and simply prefix it with a value of your choice (or convert to a BigInteger if your can support larger numbers). To obtain universally unique IDs, consider using a UUID implementation, like the Java UUID.

IDs generated within a single JVM are guaranteed to be in order with no duplicates (read Year 2262 and beyond further down). The sequence usually has many gaps.

Generated IDs are long primitives. Java long values are 64-bit whereas standard UUID are byte arrays of 128-bit (plus the array reference itself). When using UUIDs in their common hexadecimal string format, they usually are at least 576-bit (plus the string reference).

The reduced byte size of long values compared to most strings may lead to lookup performance, in addition of some system sorting primitive numbers faster than strings. While not especially optimized for ID generation, creating long-based IDs is much faster than most string-based approach. For instance, this class is typically more than 20 times faster at generating long values than Java UUID at generating strings. An average desktop computer can show it takes less than 50 milliseconds to generate 1 million IDs (single thread).

Be advised this implementation does not account for the possibility of a backward UTC time change on the host system clock (as opposed to "local" time which can change without issues as long as UTC time is unaffected).

Assuming your application and underlying platform can achieve this feat, a maximum of 1 million unique IDs can be generated every milliseconds (1 billion IDs per seconds). Every time that threshold is reached, the method will wait until the current time has progressed to the next millisecond to prevent ID duplication (waiting 1 nanosecond at a time).

Java long values can hold 19 characters. Each digit is part of one of two groups of digits with a specific purpose. The exact pattern is the following:

 Java long max value:   9223372036854775808
 ------------------------------------------
 Current time (ms):     9223372036854          <--- max value
 Atomic sequence:                    999999    <--- max value
 

This class is thread-safe.

Year 2262 and beyond

Whenever the millisecond EPOCH representation of the current time reaches 1e14, the time representation starts back at 0ms using a modulo between the current time and 1e14. The first time this will occur is when the system UTC clock time reaches April 11th, 2262. The moment rollback of the current time value occurs, new IDs will be smaller long values than IDs generated prior to that date. If you only care about uniqueness, your IDs will still be unique unless you have been generating IDs using this class for close to 300 years or more.

Since:
1.6.0
  • Method Summary

    Modifier and Type
    Method
    Description
    static long
    Returns the last generated number since the start of this JVM (that value is not persisted anywhere outside the JVM memory).
    static long
    Generates a new number unique within this JVM.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • last

      public static long last()
      Returns the last generated number since the start of this JVM (that value is not persisted anywhere outside the JVM memory). Invoking this method before having called next() at least once will return -1.
      Returns:
      the last id generated
    • next

      public static long next()
      Generates a new number unique within this JVM.
      Returns:
      a long value