java idgenerator_全局唯一ID生成器浅析

本文介绍了Java中实现全局唯一ID的IdGen类,包括其工作ID、数据中心ID、序列号的设置,以及如何处理时钟回退问题,确保在高并发下生成不重复的ID。
摘要由CSDN通过智能技术生成

/*** 全局唯一ID生成器*/

publicclassIdGen {

privatelongworkerId;

privatelongdatacenterId;

privatelongsequence = 0L;

privatelongtwepoch = 1288834974657L;//Thu, 04 Nov 2010 01:42:54 GMTprivatelongworkerIdBits = 5L;//节点ID长度privatelongdatacenterIdBits = 5L;//数据中心ID长度privatelongmaxWorkerId = -1L ^ (-1L <

privatelonglastTimestamp = -1L;

privatestaticclassIdGenHolder {

privatestaticfinalIdGen instance =newIdGen();

}

publicstaticIdGen get(){

returnIdGenHolder.instance;

}

publicIdGen() {

this(0L, 0L);

}

publicIdGen(longworkerId,longdatacenterId) {

if(workerId > maxWorkerId || workerId 

thrownewIllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));

}

if(datacenterId > maxDatacenterId || datacenterId 

thrownewIllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));

}

this.workerId = workerId;

this.datacenterId = datacenterId;

}

publicsynchronizedlongnextId() {

longtimestamp = timeGen();//获取当前毫秒数//如果服务器时间有问题(时钟后退) 报错。

if(timestamp 

thrownewRuntimeException(String.format(

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

}

//如果上次生成时间和当前时间相同,在同一毫秒内

if(lastTimestamp == timestamp) {

//sequence自增,因为sequence只有12bit,所以和sequenceMask相与一下,去掉高位

sequence = (sequence + 1) & sequenceMask;

//判断是否溢出,也就是每毫秒内超过4095,当为4096时,与sequenceMask相与,sequence就等于0

if(sequence == 0) {

timestamp = tilNextMillis(lastTimestamp);//自旋等待到下一毫秒

}

}else{

sequence = 0L;//如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加

}

lastTimestamp = timestamp;

// 最后按照规则拼出ID。

// 000000000000000000000000000000000000000000  00000            00000       000000000000

// time                        datacenterIdworkerIdsequencereturn((timestamp - twepoch) <

| (workerId <

}

protectedlongtilNextMillis(longlastTimestamp) {

longtimestamp = timeGen();

while(timestamp <= lastTimestamp) {

timestamp = timeGen();

}

returntimestamp;

}

protectedlongtimeGen() {

returnSystem.currentTimeMillis();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值