Java实现雪花算法

Java实现雪花算法

雪花算法(Snowflake Algorithm)是一种分布式系统中生成唯一ID的方法,由Twitter公司开源。它可以在不依赖数据库的情况下,生成全局唯一、有序递增的ID,适用于高并发的场景。

雪花算法的原理

雪花算法生成的ID是一个64位的整数,由以下四部分组成:

  • 第一位:符号位,固定为0,表示正数。
  • 第二部分:41位时间戳,表示从某个固定时间点(如2020年1月1日)到当前时间的毫秒数。可以支持约140年的时间范围。
  • 第三部分:10位机器标识,可以由数据中心ID和工作节点ID两部分组成,用来区分不同的机器。可以支持最多1024个节点。
  • 第四部分:12位序列号,表示同一毫秒内产生的不同ID。可以支持每毫秒最多4096个ID。

这四部分按照顺序拼接在一起,就构成了一个64位的整数,转换为十进制就是我们需要的唯一ID。由于时间戳在高位,并且随着时间增加而增加,所以生成的ID也是有序递增的。

雪花算法的优缺点

雪花算法有以下几个优点:

  • 生成ID时不依赖于数据库,避免了数据库访问压力和性能瓶颈。
  • ID按照时间有序递增,对于基于时间排序或者需要按照时间区间查询等场景非常有利。
  • ID是全局唯一且不重复的,满足了分布式系统中多个服务协作产生数据时对唯一标识符的需求。

雪花算法也有以下几个缺点:

  • 依赖于系统时钟,如果系统时钟回拨或者不同机器之间时钟不同步会导致重复ID或者无法生成ID。
  • ID长度比较长(64位),如果存储空间有限或者对传输效率要求高可能会有影响。
  • ID含义不明确,无法从中获取其他信息(如创建时间、创建者等)。

Java编程实现雪花算法

下面给出一个简单的Java代码示例来实现雪花算法:
下面展示一些 内联代码片

public class SnowFlake {

//起始时间戳(2020年1月1日)
private final static long START_TIME = 1577808000000L;

//时间戳占用的位数
private final static long TIME_BITS = 41L;

//机器标识占用的位数
private final static long WORKER_BITS = 10L;

//序列号占用的位数
private final static long SEQUENCE_BITS = 12L;

//机器标识最大值(1023)
private final static long MAX_WORKER_ID = ~(-1L << WORKER_BITS);

//序列号最大值(4095)
private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);

//机器标识左移位数(12)
private final static long WORKER_SHIFT = SEQUENCE_BITS;

//时间戳左移位数(22)
private final static long TIME_SHIFT = WORKER_BITS + SEQUENCE_BITS;

//上一次生成ID时的时间戳
private long lastTime = -1L;

//序列号
private long sequence = 0L;

//机器标识
private long workerId;

/**
* 构造方法
* @param workerId 机器标识(0~1023)
*/
public SnowFlake(long workerId) {
if (workerId < 0 || workerId > MAX_WORKER_ID) {
throw new IllegalArgumentException("workerId must be between 0 and " + MAX_WORKER_ID);
}
this.workerId = workerId;
}

/**
* 生成下一个ID
* @return ID
*/
public synchronized long nextId() {
long currentTime = System.currentTimeMillis();
if (currentTime < lastTime) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
雪花算法(Snowflake)是一种用于生成全局唯一ID的算法,常用于分布式系统中,主要包括时间戳、机器ID和序列号三个部分。下面是一个简单的Java实现雪花算法的示例代码: ```java public class Snowflake { private static final long START_TIMESTAMP = 1609459200000L; // 2021-01-01 00:00:00 private long workerId; private long sequence = 0L; private long lastTimestamp = -1L; public Snowflake(long workerId) { this.workerId = workerId; } public synchronized long nextId() { long currentTimestamp = System.currentTimeMillis(); if (currentTimestamp < lastTimestamp) { throw new IllegalStateException("Invalid system clock"); } if (currentTimestamp == lastTimestamp) { sequence = (sequence + 1) & 0x1FFF; // 0x1FFF = 8191 if (sequence == 0) { currentTimestamp = waitNextMillis(currentTimestamp); } } else { sequence = 0L; } lastTimestamp = currentTimestamp; return ((currentTimestamp - START_TIMESTAMP) << 22) | (workerId << 12) | sequence; } private long waitNextMillis(long currentTimestamp) { long timestamp = System.currentTimeMillis(); while (timestamp <= currentTimestamp) { timestamp = System.currentTimeMillis(); } return timestamp; } } ``` 使用示例: ```java public class SnowflakeExample { public static void main(String[] args) { Snowflake snowflake = new Snowflake(1); for (int i = 0; i < 10; i++) { long id = snowflake.nextId(); System.out.println(id); } } } ``` 在上述示例中,通过传入不同的workerId来区分不同的机器或节点,生成全局唯一的ID。请注意,这只是一个简单的实现示例,实际应用中需要根据具体情况进行调整和优化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值