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
-
Can you take current time, then during each loop add 1 to the millisecond count, and write that to the db (it may not be accurate but it will be unique).. – PP. Dec 02 '09 at 11:13
-
System.currentTimeMillis() is depends , How operating system measure the time. – nayakam Dec 02 '09 at 11:21
-
thanks for the inputs - would probably implement with an internal counter and resynch the clock in a predetermined interval - note : maybe i should have phrased the question in a different way initially - requirement for the timestamp is not to generate the uid - its used for versioning, auditing and ability to view the data historically as of a particular time and date etc – prabhackar Dec 03 '09 at 20:38
9 Answers
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.

- 4,143
- 3
- 25
- 27
-
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 Dec 02 '09 at 11:40
-
1@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 Dec 02 '09 at 12:42
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();

- 44,988
- 7
- 85
- 112
-
1
-
Right, to get time stamps it would probably make sense to combine it with `System.currentTimeMillis()` – Fabian Steeg Dec 02 '09 at 12:29
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.

- 5,788
- 1
- 30
- 35
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());
}
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.

- 73,784
- 33
- 194
- 347
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.

- 14,561
- 3
- 44
- 81
-
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 Dec 02 '09 at 11:25
-
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.

- 398,947
- 96
- 818
- 769
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.

- 11,171
- 2
- 38
- 49
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