package cn.shencom.scloud.common.base.snowflake;
import java.util.Random;
/**
* from https://github.com/twitter/snowflake/blob/master/src/main/scala/com/twitter/service/snowflake/IdWorker.scala
*
* @author stormning on 16/6/2.
*/
public class Snowflake{
private final long workerId;//机器识别码
private final long datacenterId;//数据中心
private final long idepoch;//起始时间戳
private static final long workerIdBits = 5L;
private static final long datacenterIdBits = 5L;
private static final long maxWorkerId = ~(-1L << workerIdBits);
private static final long maxDatacenterId = ~(-1L << datacenterIdBits);
private static final long sequenceBits = 12L;
private static final long workerIdShift = sequenceBits;
private static final long datacenterIdShift = sequenceBits + workerIdBits;
private static final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private static final long sequenceMask = ~(-1L << sequenceBits);
private long lastTimestamp = -1L;
private long sequence;
private static final Random r = new Random();
public Snowflake() {
this(1344322705519L);
}
public Snowflake(long idepoch) {
this(r.nextInt((int) maxWorkerId), r.nextInt((int) maxDatacenterId), 0, idepoch);
}
public Snowflake(long workerId, long datacenterId, long sequence) {
this(workerId, datacenterId, sequence, 1344322705519L);
}
//
public Snowflake(long workerId, long datacenterId, long sequence, long idepoch) {
this.workerId = workerId;
this.datacenterId = datacenterId;
this.sequence = sequence;
this.idepoch = idepoch;
if (workerId < 0 || workerId > maxWorkerId) {
throw new IllegalArgumentException("workerId is illegal: " + workerId);
}
if (datacenterId < 0 || datacenterId > maxDatacenterId) {
throw new IllegalArgumentException("datacenterId is illegal: " + workerId);
}
if (idepoch >= System.currentTimeMillis()) {
throw new IllegalArgumentException("idepoch is illegal: " + idepoch);
}
}
public long getDatacenterId() {
return datacenterId;
}
public long getWorkerId() {
return workerId;
}
public long getTime() {
return System.currentTimeMillis();
}
public String getId() {
return (nextId())+"";
}
private synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new IllegalStateException("Clock moved backwards.");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp - idepoch) << timestampLeftShift)//
| (datacenterId << datacenterIdShift)//
| (workerId << workerIdShift)//
| sequence;
}
/**
* get the timestamp (millis second) of id
* @param id the nextId
* @return the timestamp of id
*/
public long getIdTimestamp(long id){
return idepoch + (id >> timestampLeftShift);
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
@Override
public String toString() {
String sb = "IdWorker{" + "workerId=" + workerId +
", datacenterId=" + datacenterId +
", idepoch=" + idepoch +
", lastTimestamp=" + lastTimestamp +
", sequence=" + sequence +
'}';
return sb;
}
public static void main(String[] args) {
Snowflake idWorker = new Snowflake();
for(int i=0;i<100;i++){
String id = idWorker.getId();
System.out.println(id);
}
}
}
雪花算法~
于 2023-07-14 09:48:55 首次发布