雪花算法

导入

帮助我们在分布式系统中生成一个有序且全局唯一的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;
}
原文地址:https://www.cnblogs.com/10134dz/p/13835992.html