/*** 全局唯一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();
}
}