package org.quickbundle.tools.helper; import java.util.UUID; import org.safehaus.uuid.EthernetAddress; import org.safehaus.uuid.Logger; import org.safehaus.uuid.UUIDGenerator; public class RmUUIDHelper { private static EthernetAddress defaultEa = null; static { //defaultEa = NativeInterfaces.getPrimaryInterface(); } /** * 全局获得uuid的唯一入口方法 * @return */ public static String generateUUID() { return UUIDGenerator.getInstance().generateTimeBasedUUID().toString(); } /** * 从基于时间戳的uuid字符串,获得UUID专用时间戳 * @param uuid * @return */ public static long getTimestamp(String uuid) { UUID uu = UUID.fromString(uuid); return uu.timestamp(); } /** * Since System.longTimeMillis() returns time from january 1st 1970, * and UUIDs need time from the beginning of gregorian calendar * (15-oct-1582), need to apply the offset: */ private static final long kClockOffset = 0x01b21dd213814000L; /** * Also, instead of getting time in units of 100nsecs, we get something * with max resolution of 1 msec... and need the multiplier as well */ private static final long kClockMultiplier = 10000; private static final long kClockMultiplierL = 10000L; /** * Let's allow "virtual" system time to advance at most 100 milliseconds * beyond actual physical system time, before adding delays. */ private static final long kMaxClockAdvance = 100L; // // // Clock state: /** * Additional state information used to protect against anomalous * cases (clock time going backwards, node id getting mixed up). * Third byte is actually used for seeding counter on counter * overflow. */ private static final byte[] mClockSequence = new byte[3]; /** * Last physical timestamp value <code>System.currentTimeMillis()</code> * returned: used to catch (and report) cases where system clock * goes backwards. Is also used to limit "drifting", that is, amount * timestamps used can differ from the system time value. This value * is not guaranteed to be monotonically increasing. */ private static long mLastSystemTimestamp = 0L; /** * Timestamp value last used for generating a UUID (along with * {@link #mClockCounter}. Usually the same as * {@link #mLastSystemTimestamp}, but not always (system clock * moved backwards). Note that this value is guaranteed to be * monotonically increasing; that is, at given absolute time points * t1 and t2 (where t2 is after t1), t1 <= t2 will always hold true. */ private static long mLastUsedTimestamp = 0L; /** * First timestamp that can NOT be used without synchronizing * using synchronization object ({@link #mSync}). Only used when * external timestamp synchronization (and persistence) is used, * ie. when {@link #mSync} is not null. */ private static long mFirstUnsafeTimestamp = Long.MAX_VALUE; /** * Counter used to compensate inadequate resolution of JDK system * timer. */ private static int mClockCounter = 0; public static long getSysTimestamp() { long systime = System.currentTimeMillis(); /* Let's first verify that the system time is not going backwards; * independent of whether we can use it: */ if (systime < mLastSystemTimestamp) { Logger.logWarning("System time going backwards! (got value "+systime+", last "+mLastSystemTimestamp); // Let's write it down, still mLastSystemTimestamp = systime; } /* But even without it going backwards, it may be less than the * last one used (when generating UUIDs fast with coarse clock * resolution; or if clock has gone backwards over reboot etc). */ if (systime <= mLastUsedTimestamp) { /* Can we just use the last time stamp (ok if the counter * hasn't hit max yet) */ if (mClockCounter < kClockMultiplier) { // yup, still have room systime = mLastUsedTimestamp; } else { // nope, have to roll over to next value and maybe wait long actDiff = mLastUsedTimestamp - systime; long origTime = systime; systime = mLastUsedTimestamp + 1L; Logger.logWarning("Timestamp over-run: need to reinitialize random sequence"); } } else { /* Clock has advanced normally; just need to make sure counter is * reset to a low value (need not be 0; good to leave a small * residual to further decrease collisions) */ mClockCounter &= 0xFF; } mLastUsedTimestamp = systime; /* Now, let's translate the timestamp to one UUID needs, 100ns * unit offset from the beginning of Gregorian calendar... */ systime *= kClockMultiplierL; systime += kClockOffset; // Plus add the clock counter: systime += mClockCounter; return systime; } public static void main(String[] args) { System.out.println(getSysTimestamp()); } }