美文网首页
雪花算法(ip+进程pid)

雪花算法(ip+进程pid)

作者: 白衣如相 | 来源:发表于2018-09-26 14:19 被阅读0次
    import java.lang.management.ManagementFactory;
    import java.math.BigInteger;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 产生唯一ID的snow flake
     * 41(timestamp)+16(ip)+18(pid)+8(seq)
     * 
     * @author changstone
     *
     */
    public class Snowflake {
        /**
         * 纪元开始,2018-01-01
         */
        private static final long TH_EPOCH = 1514736000000L;
    
        private int timestampBits = 41;
        private int ipBits = 16;
        private int processIdBits = 18;
        private int sequenceBits = 8;
        
        @SuppressWarnings("unused")
        private long maxTimestamp = -1L ^ (-1L << timestampBits);
        private long maxIp = -1L ^ (-1L << ipBits);
        private long maxProcessId = -1L ^ (-1L << processIdBits);
        private long sequenceMask = -1L ^ (-1L << sequenceBits);
    
        private int processIdShift = sequenceBits;
        private int ipSfhit = sequenceBits + processIdBits;
        private int timestampShift = sequenceBits + processIdBits + ipBits;
    
        private long ip = 1L;
        private long processId = 1L;
        private long sequence = 1L;
        private long lastTimestamp = 1L;
        private final ReentrantLock lock = new ReentrantLock();
    
        public Snowflake(String ipAddr) {
            String[] ipArray = ipAddr.split("\\.");
            ip = Long.valueOf(ipArray[2]) << 8 | Long.valueOf(ipArray[3]) & maxIp;
            processId = Long.valueOf(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]) & maxProcessId;
        }
    
        private long tilNextMillis(long lastTimestamp) {
            long timestamp = 1L;
            for (;;) {
                timestamp = System.currentTimeMillis();
                if (timestamp > lastTimestamp) {
                    return timestamp;
                }
            }
        }
    
        public String nextId() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                long timestamp = System.currentTimeMillis();
                if (timestamp < TH_EPOCH) {
                    throw new RuntimeException("clock is moving backwards.Reject requests before epoch!");
                }
                if (timestamp == lastTimestamp) {
                    sequence = (sequence + 1) & sequenceMask;
                    if (sequence == 0) {
                        timestamp = tilNextMillis(lastTimestamp);
                    }
                } else {
                    sequence = 0L;
                }
                lastTimestamp = timestamp;
                long idLow = ip << ipSfhit | processId << processIdShift | sequence;
                BigInteger idHign = BigInteger.valueOf(timestamp - TH_EPOCH).shiftLeft(timestampShift);
                BigInteger id = idHign.add(BigInteger.valueOf(idLow));
                return id.toString(10);
            } finally {
                lock.unlock();
            }
        }
    
        public String nextIdHex() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                long timestamp = System.currentTimeMillis();
                if (timestamp < TH_EPOCH) {
                    throw new RuntimeException("clock is moving backwards.Reject requests before epoch!");
                }
    
                if (timestamp == lastTimestamp) {
                    sequence = (sequence + 1) & sequenceMask;
                    if (sequence == 0) {
                        timestamp = tilNextMillis(lastTimestamp);
                    }
                } else {
                    sequence = 0L;
                }
    
                lastTimestamp = timestamp;
                long idLow = ip << ipSfhit | processId << processIdShift | sequence;
                BigInteger idHign = BigInteger.valueOf(timestamp - TH_EPOCH).shiftLeft(timestampShift);
                BigInteger id = idHign.add(BigInteger.valueOf(idLow));
                return id.toString(16);
            } finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            Snowflake snow = new Snowflake("188.89.56.123");
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
            System.out.println(snow.nextId());
    
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
            System.out.println(snow.nextIdHex());
        }
    }
    

    相关文章

      网友评论

          本文标题:雪花算法(ip+进程pid)

          本文链接:https://www.haomeiwen.com/subject/llwdoftx.html