com.intters.idworker.IdWorker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of - Show documentation
Show all versions of - Show documentation
Rapid development tool class
The newest version!
package com.intters.idworker;
import com.intters.util.SystemClock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.SecureRandom;
/**
* @author Ruison
* @date 2018/7/24.
*/
public class IdWorker {
protected long epoch = 1288834974657L;
// protected long epoch = 1387886498127L; // 2013-12-24 20:01:38.127
protected long workerIdBits = 10L;
protected long maxWorkerId = -1L ^ (-1L << workerIdBits);
protected long sequenceBits = 11L;
protected long workerIdShift = sequenceBits;
protected long timestampLeftShift = sequenceBits + workerIdBits;
protected long sequenceMask = -1L ^ (-1L << sequenceBits);
protected long lastMillis = -1L;
protected final long workerId;
protected long sequence = 0L;
protected Logger logger = LoggerFactory.getLogger(IdWorker.class);
public IdWorker(long workerId) {
this.workerId = checkWorkerId(workerId);
logger.debug("worker starting. timestamp left shift {}, worker id {}", timestampLeftShift, workerId);
}
public long getEpoch() {
return epoch;
}
private long checkWorkerId(long workerId) {
// sanity check for workerId
if (workerId > maxWorkerId || workerId < 0) {
int rand = new SecureRandom().nextInt((int) maxWorkerId + 1);
logger.warn("worker Id can't be greater than {} or less than 0, use a random {}", maxWorkerId, rand);
return rand;
}
return workerId;
}
public synchronized long nextId() {
long timestamp = millisGen();
if (timestamp < lastMillis) {
logger.error("clock is moving backwards. Rejecting requests until {}.", lastMillis);
throw new InvalidSystemClock(String.format(
"Clock moved backwards. Refusing to generate id for {} milliseconds", lastMillis - timestamp));
}
if (lastMillis == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastMillis);
}
} else {
sequence = 0;
}
lastMillis = timestamp;
long diff = timestamp - getEpoch();
return (diff << timestampLeftShift) |
(workerId << workerIdShift) |
sequence;
}
protected long tilNextMillis(long lastMillis) {
long millis = millisGen();
while (millis <= lastMillis) {
millis = millisGen();
}
return millis;
}
protected long millisGen() {
return SystemClock.now();
}
public long getLastMillis() {
return lastMillis;
}
public long getWorkerId() {
return workerId;
}
}