public class SnowflakeUtil { /** 序列号占用的位数 */ private final static int SEQUENCE_BIT = 12; /** 机器标识占用的位数 */ private final static int MACHINE_BIT = 5; /** 数据中心占用的位数*/ private final static int DATACENTER_BIT = 5; /** 最大的 数据中心占用 */ private final static long MAX_DATACENTER_NUM = -1L ^(-1L << DATACENTER_BIT); /** 最大的机器标识占用 */ private final static long MAX_MACHINE_NUM = -1L ^(-1L << MACHINE_BIT); /** 最大的序列号占用 */ private final static long MAX_SEQUENCE_NUM = -1L ^(-1L << SEQUENCE_BIT); private long datacenterId; //数据中心 private long machineId; //机器标识 private long sequence = 0L; //序列号 private transient long time = 0l; ReentrantLock lock = new ReentrantLock(); public SnowflakeUtil(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 long next(){ long value = 0; try { lock.lock(); //获取当前时间 long currentTime = getNewstmp(); if(time != 0l &¤tTime < time){ lock.unlock(); return next(); } if(currentTime == time){ ++sequence; if (sequence > MAX_SEQUENCE_NUM){ System.out.println("最大值"); LockSupport.parkUntil(new Random().nextInt(100)); lock.unlock(); return next(); } }else{ sequence = 0l; } time = currentTime; value = currentTime << 17 | machineId << 12 | sequence; lock.unlock(); } catch (Exception e) { e.printStackTrace(); } return value; } /** * 获取当前时间<br> * @return */ private long getNewstmp() { return System.currentTimeMillis(); } public static void main(String[] args) { Set<Long> length = new HashSet<>(10000); SnowflakeUtil snowflakeUtil = new SnowflakeUtil(10l,15l); Long starTime = System.currentTimeMillis(); for (int i = 0;i<10000;i++){ long val = snowflakeUtil.next(); System.out.println(val); length.add(val); } System.out.println(System.currentTimeMillis() - starTime); } }
转载于:https://my.oschina.net/u/2504004/blog/2998356