package com.walker.infrastructure.utils; import com.walker.infrastructure.ServerId; import java.util.UUID; public abstract class NumberGenerator { public static final long[] DIGIT_SIZE_TABLE = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999 , 9999999999L, 99999999999L, 999999999999L, 9999999999999L, 99999999999999L, 999999999999999L, 9999999999999999L , 99999999999999999L, 999999999999999999L}; public static final int NANO_SIZE = 16; public static final long getLongSequenceNumberNano(){ // LocalDateTime localDateTime = LocalDateTime.now(); // System.out.println("getNano = " + localDateTime.getNano()); // Clock clock = Clock.systemDefaultZone(); // Instant instant = Instant.now(); // or Instant.now(); // long seconds = instant.getEpochSecond(); // long nano = instant.getNano(); // return (seconds * 1000000000 + nano); long nano = System.nanoTime(); if(nano < 0){ nano = Math.abs(nano); } long id = System.currentTimeMillis() + nano; int idSize = getDigitBitSize(id); if(idSize > NANO_SIZE){ // 超过16位,必须重新生成 id = System.currentTimeMillis() * 1000 + Long.parseLong(StringUtils.generateRandomNumber(3)); } return id; // return System.currentTimeMillis() + nano; } private static final int getDigitBitSize(long value){ for (int i = 0;; i++) if (value <= DIGIT_SIZE_TABLE[i]) return i + 1; } /** * 得到顺序数,此方法根据系统当前时间生成毫秒数。

* 对于数据量不大(通常每秒钟小于1000)的访问可以使用。
* 如果更大,可以使用getSequenceNumber()方法。 * @return */ public static final long getSequenceNumber(){ return System.currentTimeMillis(); } /** * 返回15位的数值,这是根据系统纳秒数生成的。 * @return * @date 2015-07-12 * @date 2023-06-29 重写方法,是用毫秒与纳秒结合方式生成序列,因为纯纳秒方法与虚拟机启动有关,在虚拟机不停重启时仍然会重复 */ public static final long getLongSequenceNumber(){ // long v = System.nanoTime(); // if(v < 0){ // return Math.abs(v); // } // return v; return getLongSequenceNumberNano(); } /** * 返回纳秒值长整形数字,转为字符串。 * @return * @date 2022-08-12 * @date 2023-10-07 生成支持集群的字符串ID,通过本机配置的主机ID(serverId) * @date 2023-10-13 由于id在文件命名中不能使用冒号,所以变更为下划线。 */ public static final String getLongSequenceId(){ // return String.valueOf(getLongSequenceNumber()); return new StringBuilder(ServerId.getId()) .append(StringUtils.STRING_UNDERLINE).append(NumberGenerator.getLongSequenceNumber()) .append(StringUtils.STRING_UNDERLINE).append(StringUtils.generateRandomNumber(5)).toString(); } /** * 产生32位随机字符串 * @return */ public static String generatorHexUUID(){ return UUID.randomUUID().toString(); } /** * @param args */ public static void main(String[] args) { // for(int i=0; i<3; i++){ // long startTime = System.nanoTime(); // long result = getSequenceNumber(); // System.out.println(result); // System.out.println("times: " + (System.nanoTime()-startTime)); // } // System.out.println("long sequence: " + getLongSequenceNumber()); // // long value = getSequenceNumber(); // Date date = new Date(value); // System.out.println(date); // List list = new ArrayList<>(); long startTime = 0; long nanoSecond = 0; for(int i=0; i<30; i++){ startTime = System.nanoTime(); nanoSecond = getLongSequenceNumberNano(); System.out.println(nanoSecond + ", total time = " + (System.nanoTime() - startTime)); } long mod = System.nanoTime() % 10; System.out.println(mod); } }