雪花算法

public class SnowflakeIdGenerator {

  private static final int BITS_SEQUENCE = 12;
  private static final int BITS_MACHINE_ID = 5;
  private static final int BITS_DATACENTER_ID = 5;
  private static final int SEQUENCE_MASK = (1 << BITS_SEQUENCE) - 1;
  private static final int MAX_MACHINE_ID = (1 << BITS_MACHINE_ID) - 1;
  private static final int MAX_DATACENTER_ID = (1 << BITS_DATACENTER_ID) - 1;

  private final int datacenterId;
  private final int machineId;
  private long lastTimestamp = -1;
  private int sequence = 0;

  public SnowflakeIdGenerator(int datacenterId, int machineId) {
    if (datacenterId < 0 || datacenterId > MAX_DATACENTER_ID) {
      throw new IllegalArgumentException("Invalid datacenter ID");
    }
    if (machineId < 0 || machineId > MAX_MACHINE_ID) {
      throw new IllegalArgumentException("Invalid machine ID");
    }
    this.datacenterId = datacenterId;
    this.machineId = machineId;
  }

  public synchronized long nextId() {
    long timestamp = System.currentTimeMillis();
    if (timestamp < lastTimestamp) {
      throw new RuntimeException("Clock moved backwards!");
    }
    if (timestamp == lastTimestamp) {
      sequence = (sequence + 1) & SEQUENCE_MASK;
      if (sequence == 0) {
        timestamp = tilNextMillis(lastTimestamp);
      }
    } else {
      sequence = 0;
    }
    lastTimestamp = timestamp;
    long id = ((timestamp - 1288834974657L) << (BITS_SEQUENCE + BITS_MACHINE_ID + BITS_DATACENTER_ID));
    id |= (datacenterId << (BITS_MACHINE_ID + BITS_SEQUENCE));
    id |= (machineId << BITS_SEQUENCE);
    id |= sequence;
    return id;
  }

  private long tilNextMillis(long lastTimestamp) {
    long timestamp = System.currentTimeMillis();
    while (timestamp <= lastTimestamp) {
      timestamp = System.currentTimeMillis();
    }
    return timestamp;
  }
}

Q.E.D.