java中snowflake_java代码实现Snowflake id生成

java对snowflake id生成实现如下:

import java.text.SimpleDateFormat;

import java.util.Date;

public class SnowflakeIdWorker {

/**

* Start time cut-off (1970-01-01)

*/

private final long twepoch = 0L;

/**

* Number of digits occupied by machine id

*/

private final long workerIdBits = 5L;

/**

* The number of digits occupied by the data identifier id

*/

private final long datacenterIdBits = 5L;

/**

* Supported maximum machine id, the result is 31 (this shift algorithm can quickly calculate the maximum decimal number represented by several bits of binary number)

*/

private final long maxWorkerId = -1L ^ (-1L << workerIdBits);

/**

* Supported maximum data identifier id, resulting in 31

*/

private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

/**

* Number of digits in id of sequence

*/

private final long sequenceBits = 12L;

/**

* Machine ID moved 12 bits to the left

*/

private final long workerIdShift = sequenceBits;

/**

* Data id moved 17 bits to the left (12 + 5)

*/

private final long datacenterIdShift = sequenceBits + workerIdBits;

/**

* Time truncation moves 22 bits to the left (5 + 5 + 12)

*/

private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

/**

* The mask of the generated sequence is 4095 (0b111111111111111111111 = 0xfff = 4095)

*/

private final long sequenceMask = -1L ^ (-1L << sequenceBits);

/**

* Work Machine ID (0-31)

*/

private long workerId;

/**

* Data Center ID (0-31)

*/

private long datacenterId;

/**

* Sequences in milliseconds (0-4095)

*/

private long sequence = 0L;

/**

* Time cut of last ID generation

*/

private long lastTimestamp = -1L;

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;

}

/**

* Get the next ID (this method is thread-safe)

*

* @return SnowflakeId

*/

public synchronized long nextId() {

long timestamp = timeGen();

//If the current time is less than the time stamp generated by the last ID, the system clock should throw an exception when it falls back.

if (timestamp < lastTimestamp) {

throw new RuntimeException(

String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));

}

//If it is generated at the same time, the sequence in milliseconds is performed.

if (lastTimestamp == timestamp) {

sequence = (sequence + 1) & sequenceMask;

//Sequence overflow in milliseconds

if (sequence == 0) {

//Blocking to the next millisecond to get a new timestamp

timestamp = tilNextMillis(lastTimestamp);

}

}

//Time stamp change, sequence reset in milliseconds

else {

sequence = 0L;

}

//Time cut of last ID generation

lastTimestamp = timestamp;

//Shift and assemble 64-bit ID s together by operation or operation

return ((timestamp - twepoch) << timestampLeftShift) //

| (datacenterId << datacenterIdShift) //

| (workerId << workerIdShift) //

| sequence;

}

/**

* Block to the next millisecond until a new timestamp is obtained

*

* @param lastTimestamp Time cut of last ID generation

* @return Current timestamp

*/

protected long tilNextMillis(long lastTimestamp) {

long timestamp = timeGen();

while (timestamp <= lastTimestamp) {

timestamp = timeGen();

}

return timestamp;

}

/**

* Returns the current time in milliseconds

*

* @return Current time (milliseconds)

*/

protected long timeGen() {

return System.currentTimeMillis();

}

public static void parseId(long id) {

long miliSecond = id >>> 22;

long shardId = (id & (0xFFF << 10)) >> 10;

System.err.println("Distributed id-"+id+"The generation time is:"+new SimpleDateFormat("yyyy-MM-dd").format(new Date(miliSecond)));

}

public static void main(String[] args) {

SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);

for (int i = 0; i < 10; i++) {

long id = idWorker.nextId();

System.out.println(id);

parseId(id);

}

}

}

上述main执行完结果如下:

6714362529029554176

Distributed id-6714362529029554176The generation time is:2020-09-23

Distributed id-6714362529155383296The generation time is:2020-09-23

Distributed id-6714362529159577600The generation time is:2020-09-23

Distributed id-6714362529159577601The generation time is:2020-09-23

Distributed id-6714362529159577602The generation time is:2020-09-23

Distributed id-6714362529159577603The generation time is:2020-09-23

Distributed id-6714362529159577604The generation time is:2020-09-23

Distributed id-6714362529163771904The generation time is:2020-09-23

Distributed id-6714362529163771905The generation time is:2020-09-23

Distributed id-6714362529163771906The generation time is:2020-09-23

6714362529155383296

6714362529159577600

6714362529159577601

6714362529159577602

6714362529159577603

6714362529159577604

6714362529163771904

6714362529163771905

6714362529163771906

Process finished with exit code 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值