/** * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)) * @author Polim */ public class IdWorker { private final static long twepoch = 1288834974657L; // 机器标识位数 private final static long workerIdBits = 5L; // 数据中心标识位数 private final static long datacenterIdBits = 5L; // 机器ID最大值 private final static long maxWorkerId = -1L ^ (-1L << workerIdBits); // 数据中心ID最大值 private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 毫秒内自增位 private final static long sequenceBits = 12L; // 机器ID偏左移12位 private final static long workerIdShift = sequenceBits; // 数据中心ID左移17位 private final static long datacenterIdShift = sequenceBits + workerIdBits; // 时间毫秒左移22位 private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
private static long lastTimestamp = -1L;
private long sequence = 0L; private final long workerId; private final long datacenterId;
public IdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException("worker Id can‘t be greater than %d or less than 0"); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException("datacenter Id can‘t be greater than %d or less than 0"); } this.workerId = workerId; this.datacenterId = datacenterId; }
public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { try { throw new Exception("Clock moved backwards. Refusing to generate id for "+ (lastTimestamp - timestamp) + " milliseconds"); } catch (Exception e) { e.printStackTrace(); } }