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