snowflake 不重复id代码生成类

来源:互联网 发布:幼儿园美工活动反思 编辑:程序博客网 时间:2024/06/05 19:24

不重复id代码生成类

package com.hp.snowflake;/** * An object that generates IDs. * This is broken into a separate class in case * we ever want to support multiple worker threads * per process */public class IdWorker {    private long workerId;    private long datacenterId;    private long sequence = 0L;    private long twepoch = 1288834974657L;    private long workerIdBits = 5L;    private long datacenterIdBits = 5L;    private long maxWorkerId = -1L ^ (-1L << workerIdBits);    private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);    private long sequenceBits = 12L;    private long workerIdShift = sequenceBits;    private long datacenterIdShift = sequenceBits + workerIdBits;    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;    private long sequenceMask = -1L ^ (-1L << sequenceBits);    private long lastTimestamp = -1L;    public IdWorker(long workerId, long datacenterId) {        if (workerId > maxWorkerId || workerId < 0) {            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));        }        if (datacenterId > maxDatacenterId || datacenterId < 0) {            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));        }        this.workerId = workerId;        this.datacenterId = datacenterId;    }    public synchronized long nextId() {        long timestamp = timeGen();        if (timestamp < lastTimestamp) {            throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));        }        if (lastTimestamp == timestamp) {            sequence = (sequence + 1) & sequenceMask;            if (sequence == 0) {                timestamp = tilNextMillis(lastTimestamp);            }        } else {            sequence = 0L;        }        lastTimestamp = timestamp;        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;    }    protected long tilNextMillis(long lastTimestamp) {        long timestamp = timeGen();        while (timestamp <= lastTimestamp) {            timestamp = timeGen();        }        return timestamp;    }    protected long timeGen() {        return System.currentTimeMillis();    }}

多线程测试,生成是否有重复id

package com.hp.snowflake;import java.util.HashSet;import java.util.Set;public class IdWorkerTest {    static class IdWorkThread implements Runnable {        private Set<Long> set;        private IdWorker idWorker;        public IdWorkThread(Set<Long> set, IdWorker idWorker) {            this.set = set;            this.idWorker = idWorker;        }        @Override        public void run() {            while (true) {                for(int x=0;x<10000;x++){                    long id = idWorker.nextId();                    if (!set.add(id)) {                        System.out.println("duplicate:" + id);                    }                }            }        }    }    public static void main(String[] args) {        Set<Long> set = new HashSet<Long>();        for(int x=0;x<31;x++){            final IdWorker idWorker1 = new IdWorker(x, x);            Thread t1 = new Thread(new IdWorkThread(set, idWorker1));            t1.setDaemon(true);            t1.start();        }    }}
0 0