Following the article https://chronicle.software/unique-timestamp-identifiers/, I have checked the implementation of DistributedUniqueTimeProvider.currentTimeNanos method.
long time = provider.currentTimeNanos();
long time0 = bytes.readVolatileLong(LAST_TIME);
long timeN = timestampFor(time) + hostId;
if (timeN > time0 && bytes.compareAndSwapLong(LAST_TIME, time0, timeN))
return timeN;
return currentTimeNanosLoop();
By default, it uses SystemTimeProvider
If we look inside net.openhft.chronicle.core.time.SystemTimeProvider#currentTimeNanos
long nowNS = System.nanoTime();
long nowMS = currentTimeMillis() * NANOS_PER_MILLI;
long estimate = nowNS + delta;
if (estimate < nowMS) {
delta = nowMS - nowNS;
return nowMS;
} else if (estimate > nowMS + NANOS_PER_MILLI) {
nowMS += NANOS_PER_MILLI;
delta = nowMS - nowNS;
return nowMS;
}
return estimate;
we can see that it uses non-volatile, non-atomic variable
private long delta = 0;
So the question is: Is DistributedUniqueTimeProvider.currentTimeNanos thread-safe after all? If yes, why is that?