/** * Generate next unique ID. * * @throws IllegalStateException if the clock has gone backwards by more than {@code * maxWaitForClockCatchupInMilliseconds} * @return the next unique ID as a long value. */ public long getNextId() { long timestamp = timeProvider.getTimeInMillis(); synchronized (syncObject) { // Deal with the simple case first. if (prevTimestamp < timestamp) { sequence = 0L; prevTimestamp = timestamp; return buildKey(timestamp, workerId, sequence); } // TRICK: If the clock has gone backwards we can still use // the sequence counter to generate unique IDs, so we // reset the timestamp to prevTimestamp and try our luck // with the sequence counter timestamp = prevTimestamp; // Invariant: we have handed out an ID for this timestamp // Increment and wrap sequence = ((sequence + 1) & sequenceBitMask); if (0L == sequence) { // The sequence has wrapped so we cheat and advance // the timestamp by 1ms timestamp++; log.info("Cheating, advancing timestamp by 1ms. workerId = " + workerId); prevTimestamp = timestamp; } return buildKey(timestamp, workerId, sequence); } }
private static long getCurrentTime() { return PROVIDER.currentTimeMillis(); }