封面

snow flake id生成

import java.util.concurrent.atomic.AtomicLong;


public class SnowFlakeUtils {

//比特位移位数

private final static int MACHINE_SHIFT = 10;

private final static int TIME_SHIFT = MACHINE_SHIFT + 12;

//每秒最多生成

private static final int MAX_SEQUENCE = 4095;

//生成码

private static AtomicLong sequence = new AtomicLong(-1);

//TODO 动态机器id

private static final long MACHINE_ID = machineId();


public static Long machineId() {

return 1L;

}


//防止时间回调标记

private static AtomicLong lastGenerateTime = new AtomicLong(timeForNow());


//时间回调自旋次数

private final static int MAX_ROLL_BACK_TRY_TIME = 5;

//时间回调自旋睡眠时间

private final static int ROLL_BACK_SLEEP_TIME = 1000;


/**

* 生成一个snow flake id

*

* @return snow flake id

*/

public static Long createId() {

//获取生成码与最新时间

long id = sequence.addAndGet(1);

long lastUpdateTime = timeForNow();

//时间回调尝试次数

int tryTime = 0;

for (; ; ) {

//出现时间回调,等待后再试

if (timeForNow() < lastGenerateTime.get()) {

try {

Thread.sleep(ROLL_BACK_SLEEP_TIME);

} catch (InterruptedException ignored) {


}

//尝试次数过多,抛出异常

if (tryTime++ > MAX_ROLL_BACK_TRY_TIME) {

throw new RuntimeException("time roll back");

}

} else {

//自旋次数表

int spin = 0;

for (; ; ) {

//生成码无溢出,生成交付

if (id <= MAX_SEQUENCE) {

//更新最后生成时间

if (lastUpdateTime > lastGenerateTime.get()) {

lastGenerateTime.set(lastUpdateTime);

}

return (lastUpdateTime << TIME_SHIFT | MACHINE_ID << MACHINE_SHIFT | id);

} else if (spin++ < 1000) {

//自旋时时间回调检查

if (timeForNow() < lastGenerateTime.get()){

break;

}

//生成码溢出自旋

//判断是否下一秒

if (timeForNow() > lastUpdateTime) {

//重置生成码

sequence.compareAndSet(id, -1);

//更新生成码

id = sequence.addAndGet(1);

//生成码正常,可更新最新时间避免生成码不正常更新卡时间外自旋

if (id < MAX_SEQUENCE) {

lastUpdateTime = timeForNow();

}

}

} else {

//自旋次数过多,休眠防止占用过高

try {

Thread.sleep(1);

} catch (InterruptedException ignored) {


}

spin = 0;

}

}

}

}

}


/**

* 获取最新时间

* 方便同步时间(复写,自定义时间

*

* @return

*/

public static Long timeForNow() {

return System.currentTimeMillis();

}

}


/static/fee41dec231cb23f1bbc2992a32d1191b4de874c068511a2cc952e3a186bb413.png


最近刚学了点并发就自己手搓一个雪花id生成了,应该是没什么问题的,还没学怎么单元测试,就逻辑上应该没什么问题<(。_。)>

结果又没有写作业,全在🦌代码o(╥﹏╥)o

发布评论
全部评论(10)
最新
最早
加载中...