it编程 > 编程语言 > Java

SpringBoot自定义雪花算法生成ID的实现示例

30人参与 2025-04-25 Java

雪花算法(snowflake)是一种生成唯一id的分布式算法,由twitter推出。它能生成不重复的、有时间顺序的全局唯一id。一个典型的snowflake id由64位组成,通常划分如下:

下面是一个自定义的雪花算法来生成唯一的id。这个实现类似于twitter的snowflake算法,并考虑到了线程安全。

public class snowflakeidgenerator {

    // 起始时间戳(2020-01-01 00:00:00)
    private final long twepoch = 1577836800000l;

    // 每部分占用的位数
    private final long workeridbits = 5l;
    private final long datacenteridbits = 5l;
    private final long sequencebits = 12l;

    // 最大值
    private final long maxworkerid = -1l ^ (-1l << workeridbits);
    private final long maxdatacenterid = -1l ^ (-1l << datacenteridbits);

    // 位移
    private final long workeridshift = sequencebits;
    private final long datacenteridshift = sequencebits + workeridbits;
    private final long timestampleftshift = sequencebits + workeridbits + datacenteridbits;

    // 掩码
    private final long sequencemask = -1l ^ (-1l << sequencebits);

    private long workerid;
    private long datacenterid;
    private long sequence = 0l;
    private long lasttimestamp = -1l;

    public snowflakeidgenerator(long workerid, long datacenterid) {
        if (workerid > maxworkerid || workerid < 0) {
            throw new illegalargumentexception(string.format("worker id can't be greater than %d or less than 0", maxworkerid));
        }
        if (datacenterid > maxdatacenterid || datacenterid < 0) {
            throw new illegalargumentexception(string.format("datacenter id can't be greater than %d or less than 0", maxdatacenterid));
        }
        this.workerid = workerid;
        this.datacenterid = datacenterid;
    }

    public synchronized long nextid() {
        long timestamp = timegen();

        if (timestamp < lasttimestamp) {
            throw new runtimeexception(string.format("clock moved backwards. refusing to generate id for %d milliseconds", lasttimestamp - timestamp));
        }

        if (lasttimestamp == timestamp) {
            sequence = (sequence + 1) & sequencemask;
            if (sequence == 0) {
                timestamp = tilnextmillis(lasttimestamp);
            }
        } else {
            sequence = 0l;
        }

        lasttimestamp = timestamp;

        return ((timestamp - twepoch) << timestampleftshift)
                | (datacenterid << datacenteridshift)
                | (workerid << workeridshift)
                | sequence;
    }

    protected long tilnextmillis(long lasttimestamp) {
        long timestamp = timegen();
        while (timestamp <= lasttimestamp) {
            timestamp = timegen();
        }
        return timestamp;
    }

    protected long timegen() {
        return system.currenttimemillis();
    }

    public static void main(string[] args) {
        snowflakeidgenerator generator = new snowflakeidgenerator(1, 1);
        for (int i = 0; i < 10; i++) {
            system.out.println(generator.nextid());
        }
    }
}

说明

使用示例

运行上述代码,你会看到生成的唯一id,它们是按时间顺序递增的,每个id包含了时间戳、数据中心id、工作节点id和序列号的信息。

到此这篇关于springboot自定义雪花算法生成id的实现示例的文章就介绍到这了,更多相关springboot 雪花算法生成id内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

SpringBoot实现微信扫码登录的示例代码

04-25

Java集成邮箱验证找回密码功能全过程

04-25

Java中字符串转时间与时间转字符串的操作详解

04-25

深入解析SpringBoot中#{}和${}的使用

04-25

Spring Boot读取配置文件的五种方式小结

04-25

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

04-25

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论