tags:

views:

459

answers:

9

Is there a Java API/suggestion to use instead of System.currentTimeMillis() to get current time in milli second precision on windows - requirement is two subsequent calls with a sleep time of 1ms in between should give two different time - currently i need to explicitly sleep for 15 ms to get different times

+4  A: 

Since Java 1.5 you can use System.nanoTime() for micro benchmarks with higher precision. As the fixed time this is based on may change (see Javadoc for the method), it might make sense to combine it with System.currentTimeMillis(), e.g.

String time = System.currentTimeMillis() + "" + System.nanoTime();
Fabian Steeg
believe its used only for elapsed time
prabhackar
Right, to get time stamps it would probably make sense to combine it with `System.currentTimeMillis()`
Fabian Steeg
+1  A: 

Why do you need the times to be unique?

Take the time at the start of the transaction then add one MS for each insert.

mlk
versioning of data - there is no transaction as such - at times there might be data for the same entity updated by two threads and then i get an issue without the 15 ms delay
prabhackar
change updated to inserted
prabhackar
Use a primary key then, not the current date.
mlk
+3  A: 

It's a windows limitation. If you call System.currentTimeMillis() on other operating systems you get much higher precision.

My advise is don't use a time stamp as your source of uniqueness. Use an oracle sequence as it was designed for this problem. Otherwise use the thread name + timetamp (yuk).

OR you can use System.nanoTime(), but it's only useful for time differences, not absolute time.

David Roussel
+6  A: 

Don't attempt to use time to create unique values. Use the database to generate a unique id (key I'm assuming) for the record. Either use an auto incrementing field or create a separate table with a single record holding the counter that you can lock and update safely.

While you may get a solution that works, counting on timing to prevent a clash of resources will eventually catch up to you.

Jim Rush
i agree but i am in at a stage that its not possible to do any db design changes - worst case live with the 15ms delay
prabhackar
@prabhackar, Note: you'll also be living with issues if the system time gets off for some reason. I'm hoping you verify that timestamps don't go backwards. :)
PSpeed
+2  A: 

The resolution of the currentTimeMillis() call is dependent on the underlying operating system, and should not be relied on for creating unique stamps in your situation. Consider having a UID-singleton which can give you a long value which is incremented by one for each call, and then use that.

Thorbjørn Ravn Andersen
+1  A: 

It's important here to distinguish accuracy from precision. System.currentTimeMillis() has millisecond precision, but no guarantee whatsoever on accuracy, since it gets this from the underlying OS, and the OS gets it from the hardware, and different hardware clocks have different accuracies.

Using this for data versioning is a bad idea, since even if you had millisecond accuracy, you'd still run the risk of the occasional clash if two things happened in the same millisecond.

skaffman
A: 

Although this is not directly related to the question, I've undestood from the comments that the original attempt is to generate some version identifiers.

This is, of course, a bad idea, as detailed by other posters here.

If you can't use a database, then a better idea would be to use an AtomicInteger or AtomicLong -- then you can invoke getAndIncrement() or incrementAndGet() and not worry about any timing issues that might arise.

andri
A: 

The 15ms limitation on absolute time resolution is a feature of your operating system & interrupt rate. I'm aware that for Linux there is a kernel patch to increase the resolution to 1ms (possibly even micro sec?), not sure about Windows though. As others have commented, relative times can be resolved using System#nanoTime() (currently for micro sec precision). Either way, you should consider using db keys (or similar) for assigning unique keys.

Links

Joel
+2  A: 

Since java 1.5, you can use the java.util.UUID to generate unique IDs.

e.g

   public static void main(String[] args)
   {
      System.out.println("uuid=" + UUID.randomUUID().toString());
      System.out.println("uuid=" + UUID.randomUUID().toString());
   }
Shadi Moodad