雪花算法( 二 )


// 【此情况极少出现,但不可不防,这意味着1个毫秒内,JVM要执行此方法达到4096次,我这个电脑执行远达不到 。】
if(sequence == 0) {
currTime = unitNextTime();
}
} else {
//如果不是与lastTime一样,则表示进入了下一个毫秒,则sequence重新计数
sequence = 0L;
}
//3. 把当前时间赋值给 lastTime, 以便下一次判断是否处在同一个毫秒内
lastTimeStamp = currTime;
//4. 依次把各个部门求出来并通过逻辑或 拼接起来
return (this.lastTimeStamp << timeStampShift) | //把当前系统时间 左移22位
(this.dataCenterId << dataCenterIdShift) | //把机房编号 左移17位
(this.computerId << computerIdShift) | //把计算机号编号左移 12位
this.sequence; //最后的序列号占12位,无需移动
}
 
/******
* 等待毫秒数进入下一个时间
* @return
*/
private long unitNextTime() {
//1.再次获取系统时间
long timestamp = getCurrentTime();
//2. 判断 lastTime与currentTime是否一样
while(timestamp <= lastTimeStamp) {
//2.1 继续获取系统时间,直到上面的条件不成立为止
timestamp = getCurrentTime();
}
//3. 返回
return timestamp;
}
 
/*****
* 用来获取当前的系统时间,以毫秒为单位
* @return
*/
private long getCurrentTime() {
return System.currentTimeMillis();
}
}
 
测试类
 
public class UseIdGenerator {
/****
【雪花算法】* 主方法
* @param args
*/
public static void main(String[] args) {
//这里两个参数都是1,表示1号机房和1号电脑【在分布式系统中,每个电脑知道自己所在的机房和编号】
IdGenerator ig = new IdGenerator(1,1);
//循环生成
long result = -1;
for(int i = 0;i<100000;i++) {
result = ig.nextId();
System.out.println(result+" , "+Long.toBinaryString(result));
}
}
 
}





推荐阅读