JDK#UUID 简单优化

2019-04-24
public class UuidUtil {
    private final static char[] DIGITS_ARRAY = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    // 支持的最小进制数
    private static final int MIN_RADIX = 2;
    // 支持的最大进制数
    private static final int MAX_RADIX = DIGITS_ARRAY.length;

    public static String randomUuid() {
        // 产生UUID
        UUID uuid = UUID.randomUUID();

        // 分区转换(19位) + 当前时间戳(13位)
        return new StringBuffer()//
        .append(digits(uuid.getMostSignificantBits() >> 32, 8))//
        .append(digits(uuid.getMostSignificantBits() >> 16, 4))//
        .append(digits(uuid.getMostSignificantBits(), 4))//
        .append(digits(uuid.getLeastSignificantBits() >> 48, 4))//
        .append(digits(uuid.getLeastSignificantBits(), 12))//
        .append(System.currentTimeMillis()).toString();
    }

    /**
     * Test: 模拟并发场景下的UUID效率,唯一性。
     * 
     * @param args
     */
    public static void main(String[] args) {
        final long begin = System.currentTimeMillis();
        final int threadCount = 100;
        final int uuidCountPerThread = 10000;

        final ExecutorService executor = Executors.newCachedThreadPool();
        final Set<String> uuidSet = new ConcurrentSkipListSet<String>();

        for (int i = 0; i < threadCount; ++i) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < uuidCountPerThread; ++j) {
                        uuidSet.add(randomUuid());
                    }
                }
            });
        }
        executor.shutdown();
        while (true) {
            if (executor.isTerminated()) {
                int forecastSum = (threadCount * uuidCountPerThread);
                int actualSum = uuidSet.size();
                System.out.println(String.format("预计生成%d个,实际生成%d个,重复个数:%d, 耗时:%d",//
                    forecastSum, actualSum, forecastSum - actualSum, (System.currentTimeMillis() - begin) / 1000L));
                break;
            }
        }
    }

    private static String digits(long val, int digits) {
        long hi = 1L << (digits * 4);
        return toString(hi | (val & (hi - 1)), DIGITS_ARRAY.length).substring(1);
    }

    private static String toString(long i, int radix) {
        if (radix < MIN_RADIX || radix > MAX_RADIX) {
            radix = 10;
        }
        if (radix == 10) {
            return Long.toString(i);
        }

        final int size = 65;
        int charPos = 64;
        char[] buf = new char[size];
        boolean negative = (i < 0);
        if (!negative) {
            i = -i;
        }
        while (i <= -radix) {
            buf[charPos--] = DIGITS_ARRAY[(int) (-(i % radix))];
            i = i / radix;
        }
        buf[charPos] = DIGITS_ARRAY[(int) (-i)];
        if (negative) {
            buf[--charPos] = '-';
        }

        return new String(buf, charPos, (size - charPos));
    }
}

image.png