zoukankan      html  css  js  c++  java
  • 雪花算法

    导入

    帮助我们在分布式系统中生成一个有序且全局唯一的ID,由于自然界中并不存在两片完全一样的雪花,所以这样命名

    原理

    生成一个64位的Long类型数字id把这64位分成几个部分,每个部分都有自己的生产规则,最后拼接起来即可。

    1位标识符——代表正负,由于标识符肯定是正数,所以我们的取值一定是0

    41位时间戳精确到毫秒级别,69年(2^41^)

    10位工作机器位——我们可以部署到 1024节点上

    12位序列号用来记录同毫秒内产生的不同id既可以用——4095个数字

    算法实现

    public synchronized long nextId() {
        // 这儿就是获取当前时间戳,单位是毫秒
        long timestamp = System.currentTimeMillis();
        //获取当前时间戳如果等于上次时间戳(同一毫秒内),则序号加一,否则序号为0
        if (lastTimestamp == timestamp) {
            // 这个意思是说一个毫秒内最多只能有4096个数字,无论你传递多少进来,
            //这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围
            sequence = (sequence + 1) & sequenceMask;
            //当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生ID
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }
        // 将上次时间戳刷新
        lastTimestamp = timestamp;
        // 这儿就是最核心的二进制位运算操作,生成一个64bit的id
        // 先将当前时间戳左移22位,后面就有22个0,之后对我们的机器位左移12位,序号位无需左移,用或运算相加
        return ((timestamp - twepoch) << timestampLeftShift) |
            (datacenterId << datacenterIdShift) |
            (workerId << workerIdShift) | sequence;
    }
    
  • 相关阅读:
    Java中Vector和ArrayList的区别
    Java深拷贝与浅拷贝
    Java基础数据类型转换
    Java中的break Label 和continue Label
    java中关于Integer 和java 中方法参数传递
    网络虚拟化
    备份工具
    mysql文件理解
    mysql分区介绍
    进程间通信
  • 原文地址:https://www.cnblogs.com/10134dz/p/13835992.html
Copyright © 2011-2022 走看看