Twitter的分布式自增ID雪花算法snowflake
- 一、Twitter的分布式自增ID雪花算法snowflake
- endl
一、Twitter的分布式自增ID雪花算法snowflake
public class SnowFlake {private static final long START_STMP = 1480166465631L;private static final long SEQUENCE_BIT = 12; private static final long MACHINE_BIT = 5; private static final long DATACENTER_BIT = 5; private static final long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);private static final long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);private static final long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);private static final long MACHINE_LEFT = SEQUENCE_BIT;private static final long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;private static final long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;private long datacenterId; private long machineId; private long sequence = 0L; private long lastTimestamp = -1L; public SnowFlake(long datacenterId, long machineId) {if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");}if (machineId > MAX_MACHINE_NUM || machineId < 0) {throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");}this.datacenterId = datacenterId;this.machineId = machineId;}public synchronized long nextId() {long currentTimestamp = getNewsTimestamp();if (currentTimestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards. Refusing to generate id");}if (currentTimestamp == lastTimestamp) {sequence = (sequence + 1) & MAX_SEQUENCE;if (sequence == 0L) {currentTimestamp = getNextMill();}} else {sequence = 0L;}lastTimestamp = currentTimestamp;return (currentTimestamp - START_STMP) << TIMESTMP_LEFT | datacenterId << DATACENTER_LEFT | machineId << MACHINE_LEFT | sequence; }private long getNextMill() {long mill = getNewsTimestamp();while (mill <= lastTimestamp) {mill = getNewsTimestamp();}return mill;}private long getNewsTimestamp() {return System.currentTimeMillis();}public static void main(String[] args) {SnowFlake snowFlake = new SnowFlake(2, 3);long start = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {System.out.println("当前生成的有序数字串 : " + (snowFlake.nextId()));}System.out.println("总耗时 : " + (System.currentTimeMillis() - start));System.out.println("MAX_MACHINE_NUM : " + MAX_MACHINE_NUM);System.out.println("MAX_DATACENTER_NUM : " + MAX_DATACENTER_NUM);System.out.println("MAX_SEQUENCE : " + MAX_SEQUENCE);}
}
endl