private long workerId; private long datacenterId; private long sequence;
//开始时间,比如我想从2000-1-1开始生成日期就填入2000-1-1的时间 private long twepoch = 1288834974657L; /** * * @param workerId 机器id(占用5比特,最大为31) * @param datacenterId 机房id(占用5比特) * @param sequence (12位序列号起始编号) * long twepoch 参数开始时间,比如我想从2000-1-1开始生成日期就填入2000-1-1的时间 */ public IdWorker(long workerId, long datacenterId, long sequence){ // sanity check for workerId if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId)); } System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d", timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);
private long workerIdBits = 5L; private long datacenterIdBits = 5L; private long maxWorkerId = -1L ^ (-1L << workerIdBits); private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); private long sequenceBits = 12L;
private long workerIdShift = sequenceBits; private long datacenterIdShift = sequenceBits + workerIdBits; private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; private long sequenceMask = -1L ^ (-1L << sequenceBits);
private long lastTimestamp = -1L;
public long getWorkerId(){ return workerId; }
public long getDatacenterId(){ return datacenterId; }
public long getTimestamp(){ return System.currentTimeMillis(); }
public synchronized long nextId() { long timestamp = timeGen();
if (timestamp < lastTimestamp) { System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp); throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); }
private long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; }
private long timeGen(){ return System.currentTimeMillis(); }
//---------------测试--------------- public static void main(String[] args) { IdWorker worker = new IdWorker(3,1,1); for (int i = 0; i < 30; i++) { System.out.println(worker.nextId()); } }