This week's book giveaway is in the Reactive Progamming forum.
We're giving away four copies of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams and have Adam Davis on-line!
See this thread for details.
Win a copy of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams this week in the Reactive Progamming forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

currentTimeMillis as UniqueIDGenerator

 
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I wanted to explore various patterns to generate a unique long value. I had a few queries regarding currentTimeMilllis with this regard. First what exactly does the api mean when it says the actual granularity of the return value is OS dependent. Do they mean to say my Mac does not time 1ms as the standard 1ms and instead evaluates 1-2 ms in real time as it's 1ms. Or are they suggesting that it isnt precise?

Now with this mind, what are the limitations of unique currentTimeMillis as a standlone unique id generator? Should i club it with somthing more unique like a mac address or something. Any other suggestions?
 
Bartender
Posts: 10777
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Shridhar Raghavan wrote:Do they mean to say my Mac does not time 1ms as the standard 1ms and instead evaluates 1-2 ms in real time as it's 1ms. Or are they suggesting that it isnt precise?


I'd suggest that, for your purposes, the two things are the same.

Now with this mind, what are the limitations of unique currentTimeMillis as a standlone unique id generator? Should i club it with somthing more unique like a mac address or something.


The limitations are exactly what you've already observed. My clunky old Dell can create roughly 100 million Objects a second, and even if you don't get that sort of performance with your own classes, you will probably be able to create them very quickly indeed. A MAC address (if you can obtain it easily) might not be a bad idea if the ID needs to span more than one machine, but it still won't change the fact that you could create several objects in the same clock tick on the same machine.

Any other suggestions?


Yes. Have a look at java.util.UUID.

Alternatively, an object containing 2 longs:
1. System.currentTimeMillis();
2. Random.nextLong();
is likely to be pretty unique too.

Winston
 
Ranch Hand
Posts: 492
Firefox Browser VI Editor Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
just returns the current count of milliseconds since midnight, January 1, 1970. It gets this number from the underlying OS. In some OS'es the OS doesn't update the millisecond count every millisecond, but might do it every 10,20, or 40 milliseconds because that is just how the OS designers chose to group time.

It may not be the best idea to generate IDs using this method, since there is no way of guaranteeing that it will work the same on multiple operating systems.

Alternate Solution:
Is there something wrong with having a start ID of 1 and increment that ID every time to assign one?


Hope this helps,
Hunter
 
Winston Gutkowski
Bartender
Posts: 10777
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hunter McMillen wrote:Is there something wrong with having a start ID of 1 and increment that ID every time to assign one?


Not unless the ID needs to be unique across JVM sessions. I presume this may not be enough since Shridhar already asked about MAC addresses.

Winston
 
Hunter McMillen
Ranch Hand
Posts: 492
Firefox Browser VI Editor Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:
Not unless the ID needs to be unique across JVM sessions. I presume this may not be enough since Shridhar already asked about MAC addresses.

Winston



That would be true, but it seemed to me that MAC addresses only got mentioned because of their uniqueness.

Hunter
 
Winston Gutkowski
Bartender
Posts: 10777
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Hunter McMillen wrote:That would be true, but it seemed to me that MAC addresses only got mentioned because of their uniqueness.


Yes, but a simple sequence would repeat between JVM sessions. If the ID needs to be saved, I suspect that won't be enough.

Winston
 
Marshal
Posts: 67289
170
Mac Mac OS X IntelliJ IDE jQuery Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If a database is involved, a sequence might serve the purpose.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are many reasons why System.currentTimeMillis() is not suitable as a unique ID generator:
  • Any modern computer can generate millions of objects in a millisecond. So System.currentTimeMillis() is too slow - it can generate only at most 1000 values per second (1 ms = 1/1000 second).
  • If your program is multi-threaded and you have a multi-core CPU, then different cores might be creating objects at the same time. So an ID generator based solely on the current time cannot guarantee unique values.
  • If the system clock is adjusted (many computers synchronize the clock via an Internet time service, for example), then it is possible that for a while the same values are generated.

  •  
    Shridhar Raghavan
    Ranch Hand
    Posts: 71
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Any modern computer can generate millions of objects in a millisecond. So System.currentTimeMillis() is too slow.

    While speed in this context is an issue i can work around this by creating a large enough set of row ids before catering to any request right?

    If your program is multi-threaded and you have a multi-core CPU, then different cores might be creating objects at the same time

    Can i work around this using thread synchronisation and separate the row id generation routines from being thread aware? I mean when a new thread is spawned, each thread does not create a new row id, but rather fetches a row id from a collection of possible values. This fetching can be thread safe and the creation process of row ids can be separated.

    If the system clock is adjusted

    This is problematic. Will think on this. Any comments on the above?


     
    Shridhar Raghavan
    Ranch Hand
    Posts: 71
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi,

    Could someone clarify the doubts I raised.
     
    Winston Gutkowski
    Bartender
    Posts: 10777
    71
    Hibernate Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Shridhar Raghavan wrote:Hi,
    Could someone clarify the doubts I raised.


    I don't see any doubts, I see unknowns. Do you want a row id (ie, an identifier to a database row), or a unique identifier for a Java object? The two are NOT the same.

    As far as the first is concerned, you don't have to worry about Threads; the database will handle it. As for the second, did you look at UUID, as I suggested in my first post? Again, with it, Threads should not be a concern, since the likelihood of two Threads producing the same UUID is virtually impossible (but NOT 0).

    You also haven't answered the question whether this ID is supposed to be unique across machines. Again, the chances are that a UUID will be unique that way too, but the probability of collision goes up with the number of machines (you'd still have to have several hundred before "virtually impossible" becomes "almost impossible" though).

    Winston
     
    Shridhar Raghavan
    Ranch Hand
    Posts: 71
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi,

    First i desire to persist a long row id in the database and not an object identifier. Secondly, at present i do not foresee requiring the id to be unique across machines. But rather than exploit sequences by the databases i would like to write a unique id generation algorithm. So i was searching for mechanisms to achieve that using present tools.
     
    Winston Gutkowski
    Bartender
    Posts: 10777
    71
    Hibernate Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Shridhar Raghavan wrote:First i desire to persist a long row id in the database and not an object identifier.


    Again, I'm not quite sure what you mean here. A database uses a row id to uniquely identify a database row. It may or may not give you explicit access to it; you'd need to read the documentation. If you mean a unique identifier to a row in a table (eg, for use as a primary key) then there are two basic possibilities:
    1. An existing identifier (eg, National ID number, SKU, IBAN or Barcode) produced according to written specifications.
    2. A sequence number.

    Secondly, at present i do not foresee requiring the id to be unique across machines. But rather than exploit sequences by the databases i would like to write a unique id generation algorithm. So i was searching for mechanisms to achieve that using present tools.


    Then I would definitely suggest a UUID. It is a class designed to do precisely what you want, and uses an established written standard (RFC 4122) to do it. Furthermore, it is time-based (which was one of your original concerns) and already provides practical certainty of uniqueness across machines. Because of this, it is also Thread-safe.

    Winston

    Edit: Having looked at the API for version 7, UUID still doesn't appear to have an automated method for generating time-based UUIDs, so you'll have to create them yourself (the algorithm is described in the RFC). Alternatively, there are 3rd party libraries (eg, JUG) that will do it, or you can use the randomUUID() factory to generate a random one.
     
    Get out of my mind! Look! A tiny ad!
    Java file APIs (DOC, XLS, PDF, and many more)
    https://products.aspose.com/total/java
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!