15位自增Id与11位不重复Id

背景

由于使用推特的雪花算法,导致Long类型数据返回前端精度丢失,因此顺手自己定义了一个15位自增长ID生成方法和11位不重复Key

代码

废话不多说,上代码。

public class SnowUtils {
    private static final int minNum = 1024;
    private static final int strMinNum = 100;
    private static final AtomicInteger bigAtomic = new AtomicInteger(minNum);
    private static final AtomicInteger strAtomic = new AtomicInteger(strMinNum);
    private static Integer machineCode=null;
    private static Long recordSecond=null;
    private static Long recordTimeMillis=null;

    private static void checkAndInit() {
        if(machineCode==null){
            synchronized (SnowUtils.class){
                if(machineCode==null){
                    initData();
                }
            }
        }
    }

    private static void initData(){
        recordSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        recordTimeMillis = System.currentTimeMillis();
        try {
            String machineIp = InetAddress.getLocalHost().getHostAddress();
            String codeStr = machineIp.substring(machineIp.length() - 1);
            machineCode = new BigInteger(codeStr).intValue();
        } catch (UnknownHostException e) {
            machineCode = 3;
        }
    }

    /**
     * 获取15位长度的自增长Key
     * 每秒可生成8970个不重复编号
     * @return long
     */
    public static Long bigKey() {
        checkAndInit();
        if (LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) != recordSecond) {
            recordSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
            bigAtomic.set(minNum);
        }
        String differ = String.valueOf(recordSecond);
        int atomic = bigAtomic.getAndIncrement();
        if (atomic == 9999) {
            String text = "bigKey超出阈值:" + LocalDateTime.now().toString();
            throw new RuntimeException(text);
        }
        return new BigInteger(differ + atomic + machineCode).longValue();
    }

    /**
     * 获取11位不重复Key
     * 每毫秒可生成890个不重复的11位编号
     * @return String
     */
    public static String strKey() {
        checkAndInit();
        long localTimeMillis=System.currentTimeMillis();
        if(localTimeMillis!=recordTimeMillis){
            recordTimeMillis = localTimeMillis;
            strAtomic.set(strMinNum);
        }
        String differ = String.valueOf(recordTimeMillis);
        int atomic = strAtomic.getAndIncrement();
        long bigNum=new BigInteger(differ+atomic+machineCode).longValue();
        if (atomic == 999) {
            String text = "strKey超出阈值:" + LocalDateTime.now().toString();
            throw new RuntimeException(text);
        }
        return Long.toUnsignedString(bigNum,32).toUpperCase();
    }
}

讲点废话,由于阈值限制,生成ID有一定条件。由于我所用的服务器节点内网IP最后一位不一样,因此我用最后一位做机器码,如超过很多节点或者多节点下内网ip最后一位存在重复,请看注释酌情使用,或者自行修改。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值