java生成一个京i+顺序生成的id共六位数
时间: 2024-05-15 11:17:03 浏览: 84
以下是一个简单的Java代码来生成京I顺序生成的6位数ID:
```
import java.util.concurrent.atomic.AtomicInteger;
public class SequentialIDGenerator {
private static AtomicInteger counter = new AtomicInteger(0);
public static String generate() {
int value = counter.getAndIncrement();
String id = String.format("%06d", value);
return "京I" + id;
}
}
```
这个代码使用了Java中的AtomicInteger来保证线程安全的自增操作。每次调用`generate()`方法,它会返回一个新的6位数ID,格式为"京Ixxxxxx",其中的"xxxxxx"部分是一个从0开始不断递增的数字。
相关问题
java 获取一个雪花算法生成的id
要在Java中获取雪***算法实现。Snowflake算法生成的ID是一个64位的长整型数字,由以下几部分组成:
1. 时间戳(41位):记录生成ID的时间,精确到毫秒级别。
2. 工作机器ID(10位):标识不同的工作机器。
3. 序列号(12位):在同一毫秒内,按顺序递增生成的序列号。
以下是一个示例代码,演示如何使用Java获取雪花算法生成的ID:
```java
public class SnowflakeIdGenerator {
// 定义开始时间戳,可以根据自己的需求进行调整
private static final long START_TIMESTAMP = 1609459200000L; // 2021-01-01 00:00:00
// 定义每部分占用的位数
private static final long SEQUENCE_BITS = 12; // 序列号占用位数
private static final long WORKER_ID_BITS = 10; // 工作机器ID占用位数
private static final long TIMESTAMP_BITS = 41; // 时间戳占用位数
// 定义每部分的最大值
private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS);
private static final long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BITS);
// 定义每部分向左的位移
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
// 工作机器ID
private long workerId;
// 序列号
private long sequence = 0L;
// 上次生成ID的时间戳
private long lastTimestamp = -1L;
public SnowflakeIdGenerator(long workerId) {
if (workerId > MAX_WORKER_ID || workerId < 0) {
throw new IllegalArgumentException("Worker ID超出范围");
}
this.workerId = workerId;
}
public synchronized long generateId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new RuntimeException("时钟回拨异常");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp - START_TIMESTAMP) << TIMESTAMP_SHIFT)
| (workerId << WORKER_ID_SHIFT)
| sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
```
使用示例:
```java
public class Main {
public static void main(String[] args) {
SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1L); // 设置工作机器ID为1
long id = idGenerator.generateId();
System.out.println("生成的ID:" + id);
}
}
```
上述代码中,SnowflakeIdGenerator类封装了雪花算法的实现细节。在使用时,通过创建SnowflakeIdGenerator对象,并调用generateId()方法,即可生成一个雪花算法生成的ID。
注意:为了确保唯一性和正确性,请保证不同的工作机器ID(workerId)和不同的时间戳。
雪花id生成代码java
雪花算法(Snowflake Algorithm)是Twitter开源的分布式ID生成算法,其核心思想是使用一个64位的long型的数字作为全局唯一ID。这个64位的ID(默认情况下)可以分成以下几个部分:
1. 第一位是未使用的符号位,始终为0。
2. 接下来的41位是时间戳,精确到毫秒级,41位时间戳可以使用69年。
3. 然后是5位的数据中心ID和5位的机器ID。这10位可以部署在1024个节点,包括5位datacenterId和5位workerId。
4. 最后12位是毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间戳)产生4096个ID序号。
以下是一个简单的Java实现示例:
```java
public class SnowflakeIdWorker {
// ==============================Fields===========================================
/** 开始时间截 (2015-01) */
private final long twepoch = 1420041600000L;
/** 机器id所占的位数 */
private final long workerIdBits = 5L;
/** 数据标识id所占的位数 */
private final long datacenterIdBits = 5L;
/** 支持的最大机器id,结果是31 */
private final long maxWorkerId = -1L << workerIdBits);
/** 支持的最大数据标识id,结果是31 */
private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
/** 序列在id中占的位数 */
private final long sequenceBits = 12L;
/** 机器ID向左移12位 */
private final long workerIdShift = sequenceBits;
/** 数据标识id向左移17位(12+5) */
private final long datacenterIdShift = sequenceBits + workerIdBits;
/** 时间截向左移22位(5+5+12) */
private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
/** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
/** 工作机器ID(0~31) */
private long workerId;
/** 数据中心ID(0~31) */
private long datacenterId;
/** 毫秒内序列(0~4095) */
private long sequence = 0L;
/** 上次生成ID的时间截 */
private long lastTimestamp = -1L;
//==============================Constructors=====================================
/**
* 构造函数
* @param workerId 工作ID (0~31)
* @param datacenterId 数据中心ID (0~31)
*/
public SnowflakeIdWorker(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;
}
// ==============================Methods==========================================
/**
* 获得下一个ID (该方法是线程安全的)
* @return SnowflakeId
*/
public synchronized long nextId() {
long timestamp = timeGen();
//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
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;
}
//上次生成ID的时间截
lastTimestamp = timestamp;
//移位并通过或运算拼到一起组成64位的ID
return ((timestamp - twepoch) << timestampLeftShift) |
(datacenterId << datacenterIdShift) |
(workerId << workerIdShift) |
sequence;
}
/**
* 阻塞到下一个毫秒,直到获得新的时间戳
* @param lastTimestamp 上次生成ID的时间截
* @return 当前时间戳
*/
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
/**
* 返回以毫秒为单位的当前时间
* @return 当前时间(毫秒)
*/
protected long timeGen() {
return System.currentTimeMillis();
}
//==============================Test=============================================
/** 测试 */
public static void main(String[] args) {
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
for (int i = 0; i < 1000; i++) {
long id = idWorker.nextId();
System.out.println(Long.toBinaryString(id));
System.out.println(id);
}
}
}
```
这个类在多线程环境下可以安全地工作,因为它通过`synchronized`关键字同步了`nextId()`方法。注意,`workerId`和`datacenterId`是在构造函数中设置的,它们必须在0到31之间,并且要确保每个`workerId`和`datacenterId`的组合是唯一的。
阅读全文