雪花算法如何生成id

雪花算法生成id的方法:首先新建一个id生成的类;然后新建一个调用生成id的单例工具;最后使用函数【GuuidUtil.getUUID()】直接调用即可。

雪花算法如何生成id

【相关学习推荐:com.cn/tag/java" target="_blank">java基础】

雪花算法生成id的方法:? ` N w [ H Z

1、新建一个id生成的类 SnowFlake

/**
* @Auther: lyl
* @Date: 2019/11/21 17:49
* @Description:
*/
public class SnowFlake {
/**
* 起始的时间戳
*/
pr{ , 8ivate final static long START_STMP = 1480166465631L;
/**
* 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static@ * h Y long MACHINEh a G 1_BIT = 5;  //机器标识占用的位数
private final static- @ I . long DATACENTER_BIT = 5;//数据中心占用的位Z , Q | Z数
/**
* 每一部分的最大值
*/
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private~ p V p [ / final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHIs [ } t D _ HNE_BIT);
privateA ^ + P D D final static longB A B : 8 MAX_SEQUENCE = -1L ^ (-C 4 ( b W 9 l x1L << SEQ. H ] 8 aUENCE_BIT); G * S 5;
/**7 x C
* 每一部分向左的位移
*/
private final static lon! D ^ T H }g MACHINE_LEFT = SEQUENCE_BIT;
p6 # f G G ` zrivate final static long DATACENTER_LE/ I q $ | h 1 dFT = SEQ Q x w p I dQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENI 6 wTER_BIT;
private long datacenterId;  //数据中心
private long mac- t Z _ y BhineId;    //机, H * * M g ? )器标识
private long seque! 3 x R O : , |nce = 0L; //序列号
prR 8 ivate long lastStmp = -1L;//上一次时间戳
publT u B & ( I x F ^ic SnowFlake(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || daty Y U tacenterId &g ; s p 1 f ~lt; 0) {
throw nel w Y Cw IllegalArgumentException(+ | y $  M"datacenterId can't be greater thanp T } [ a n s m MAX_DT 7 % rATACENTER_NUq O u _ 5 2M or less than 0");
}
if (mack F ; $ k 9hineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
/**
* 产生下一个ID
*
* @return
*/
public synchronized long next* t ~ x GId() {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
tL v Ohrow new RuntimeException("Clock moved backwards.  Refusing to generate id");
}
if (currStmp == lastStmp) {
//相同毫秒B R T内,S 3 ` `序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大
if (sequp 4 @ $ence == 0L) {
cur6 J d Q 8 8rStmp = getNextMill();
}
} else {
/i 8 _ K/不同毫秒内,序列号置为0
seque_ . W  ! Ence = 0L;
}
lastStmp = currStmp;
return (currStmp - START_STMP) << TIMESTMP_X + 4 % r ` ~LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT      //数据中心部分
| mac_ & O f H i d = !hi? } ( / :neId << MACHINE_LEFT            //机器标识部分
| sequence;                            //序列号部分
}
private long getNextMill() {
long mill = getNewstmp();
while (mill <= lastStmp) {
mill = getNewstmp();
}
return mill;
}
private loS x Ong getNewstmp() {
return System.currentTimeMillis();
}
public static void main(String[] args) {
SnowFlake snowFlake = new SnowFlake(2, 3);
for (int i = 0; i < (1 << 12); i++) {
System.out.println(snowFlake.nextId());
}
}
}i % S

2、为防止多线程生成重复的id,这边新建了一个调用生成id的单例工具

其中machineId和datacenterId可以放在配置文件中

i{ y ! [ U 5 Dmport java.util.concurrent.CountDownLatch;
/**
* @Auther: lys w 0 E 1 L ^ ll
*2 } n k ] 7 + : @Date: 2019/11/21 18:15
* @Description:
*/
public class GuuiX k k ` I D d F }dUtil {
private static long machineId = 0;
private static long datacenu V n x W 9terId = 0;
/**
* 单例模式创6 m z i - l建学法算法对象
* */
private enum SnowFlakeSingleton{
Singleton;
private SnowFlake snowFlake;
SnowFlak^ R ; ? | leSingleton(){
sn2 z b M c S ` # /owFlake = new SnowFlake(( [ @ _ i - KdatacenterId,machineId);
}
public SnowFlake getInstance(){
return snowFlake;
}
}
public6 , o _ Q 2 k I static long getUUID(){
return SnowFlakeSin; j T q r Wgleton.S{ | z Oingleton.getInstance().nextId();
}
puN )  H U ] =blic static void main(String[] args) {
CountDownLatch latch = new CountDoR  F { O lwnLatch(10000);
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i= k d % : { : @++) {
new Runnable() {
@Override
public void runp B a() {
System.out.println(GuuidUtil.getUUID(- D O = d l * : r));
latch.countDown();
}
}.run();
}
try {
System.out.println("主线程"+ThrQ u c J lead.currentThread().getName()+"等待子线程执行完成...");
latch.a3 h ; (wait();//阻塞当前线程,直到计数器B | o c K & ? t H的值为0
System.out.println("主线程"+Thread.currentThread().t O D i 3 X 0 ~ |getName()+"s P B开始执行...");
} catch (Intz - R n V T ! ! yerruptedException e) {
e.printStackTrace();
}
Syf A PstemC o 8 G G 8 # 8 (.out.print("雪花算法用时: ");
System.out.println(System.currentTimeMillis() - start);
}V m O
}

最后直接调用:GuuidUtiQ / ! e c Xl.getUUID();就可以直接生成: H -id

想了解更多编程学习,敬请G v # w J + ]关注php培u j ( F ; V w $ d训栏目!

以上就是雪花算法如何生成id的详细内容。