雪花算法

全局ID要求

  • 全局唯一性
  • 有序的递增性
  • 高可用
  • 时间上的特性

雪花算法组成

在这里插入图片描述

代码

/**
 * @author zby
 * @version 1.0
 * @description: 雪花算法
 * @date 2021/2/21 下午4:51
 */
public class SnowFlakeGenerator {
    /**
     * 机房ID
     */
    private long roomId;
    /**
     * 机器ID
     */
    private long wokerId;
    /**
     * 占用5个bit位
     */
    private long roomIdBit = 5L;
    /**
     * 占用5个bit位
     */
    private long wokerIdBit = 5L;
    /**
     * 12bit递增序列
     */
    private long sequenceBits = 12L;

    /**
     * 声明roomId最大的正整数(最大存储32个机房)
     */
    private long maxRoomId = -1L ^ (-1L << roomIdBit);
    private long maxWokerId = -1L ^ (-1L << wokerIdBit);
    /**
     * 记录sequence能够存储的最大长度
     */
    private long sequenceMask = -1L ^ (-1L << sequenceBits);

    /**
     * 设置初始时间的值
     */
    private final static long START_TIME = 1613898948942L;

    /**
     * 递增开始的序列
     */
    private long sequence;
    /**
     * 存储上一次生成的Id的时间戳
     */
    private long lastTimeStamp = -1L;

    private long wokerIdShift = sequenceBits;
    private long roomIdShift = sequenceBits + wokerIdBit;
    private long timeStampShift = sequenceBits + wokerIdBit + roomIdBit;

    public SnowFlakeGenerator(long roomId, long wokerId, long sequence) {
        if (wokerId > maxWokerId || wokerId < 0) {
            throw new IllegalArgumentException("wokerder Id error");
        }
        if (roomId > maxRoomId || roomId < 0) {
            throw new IllegalArgumentException("room Id error");
        }
        if (sequence > sequenceMask || sequence < 0) {
            throw new IllegalArgumentException("sequence error");
        }
        this.roomId = roomId;
        this.wokerId = wokerId;
        this.sequence = sequence;
    }

    /**
     * 生成下个递增序列
     * @param evenNumber true 偶数;false 奇数
     * @return
     */
    public synchronized long nextVal(boolean evenNumber) {
        long currentTimeMillis = System.currentTimeMillis();
        if (currentTimeMillis < lastTimeStamp) {
            throw new RuntimeException("时间戳异常");
        }
        if (lastTimeStamp == currentTimeMillis) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0L) {
                currentTimeMillis = waitToNextMills(lastTimeStamp);
            }
        } else {
            /**
             * true:如果进入到了新的时间毫秒,sequence从0开始
             * false:相同毫秒内,序列号随机获取
             */
            sequence = evenNumber ?  sequence = 0L : currentTimeMillis & 1;
        }
        lastTimeStamp = currentTimeMillis;
        return ((currentTimeMillis - START_TIME) << timeStampShift | (roomId << roomIdShift) | (wokerId << wokerIdShift) | sequence);
    }

    private long waitToNextMills(long lastTimeStamp) {
        long timeMillis = System.currentTimeMillis();
        while (timeMillis <= lastTimeStamp) {
            timeMillis = System.currentTimeMillis();
        }
        return timeMillis;
    }

    public static void main(String[] args) throws InterruptedException {
        SnowFlakeGenerator snowFlaskGenerator = new SnowFlakeGenerator(1, 1, 1);
        for (int i = 0; i < 8; i++) {
            /**
             * 测试一:时间连续,齐偶数都有
             * 705700640722944
             * 705700644917248
             * 705700644917249
             * 705700644917250
             * 705700644917251
             * 705700644917252
             * 705700644917253
             * 705700644917254
             */
//            System.out.println(snowFlaskGenerator.nextVal(true));

            /**
             * 测试二:时间不连续,都是偶数
             * 707110874779648
             * 707110878973952
             * 707110883168256
             * 707110891556864
             * 707110895751168
             * 707110899945472
             * 707110908334080
             * 707110912528384
             */
//            Thread.sleep(1);
//            System.out.println(snowFlaskGenerator.nextVal(true));

            /**
             * 测试三:时间不连续,齐偶数都有
             * 708009957396480
             * 708009965785088
             * 708009969979393
             * 708009974173696
             * 708009982562304
             * 708009986756609
             * 708009990950912
             * 708009995145217
             */
            Thread.sleep(1);
            System.out.println(snowFlaskGenerator.nextVal(false));

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值