zoukankan      html  css  js  c++  java
  • Twitter Snowflake 的Java实现

    在关闭显示的情况下, 可以达到每毫秒3万个的生成速度

    /**
     * An Implementation of Twitter Snowflake ID Generator
     */
    public class SnowflakeId {
        private final static long EPOCH = 0L; // shift for smaller timestamp
        private final static long DEVICE_ID_BITS = 2L;
        private final static long SEQUENCE_BITS = 16L;
        private final static long MAX_WORKER_ID = -1L ^ -1L << DEVICE_ID_BITS; // 与& 非~ 或| 异或^, only the bit on WORKER_ID_BITS are 1
        private final static int SEQUENCE_MASK = (int)(-1L ^ -1L << SEQUENCE_BITS);
    
        private final long deviceId;
        private final RecyclableAtomicInteger atomic = new RecyclableAtomicInteger();
        private long lastTimestamp = -1L;
    
        public SnowflakeId(final long deviceId) {
            if (deviceId > MAX_WORKER_ID || deviceId < 0) {
                throw new IllegalArgumentException(
                        String.format("Device ID should be between 0 and %d", this.MAX_WORKER_ID));
            }
            this.deviceId = deviceId;
        }
    
        public long nextId() {
            long timestamp = millisecond();
            if (timestamp < lastTimestamp) {
                throw new IllegalArgumentException(
                        String.format("Wait %d milliseconds", lastTimestamp - timestamp));
            }
    
            if (lastTimestamp == timestamp) {
                int sequence = atomic.incrementAndRecycle(SEQUENCE_MASK);
                if (sequence == 0) {
                    timestamp = waitTilNextMillis(lastTimestamp);
                    lastTimestamp = timestamp;
                }
                return (timestamp - EPOCH << (SEQUENCE_BITS + DEVICE_ID_BITS)) | (deviceId << SEQUENCE_BITS) | sequence;
            } else {
                atomic.set(0);
                lastTimestamp = timestamp;
                return (timestamp - EPOCH << (SEQUENCE_BITS + DEVICE_ID_BITS)) | (deviceId << SEQUENCE_BITS);
            }
        }
    
        private long waitTilNextMillis(final long lastTimestamp) {
            System.out.print(lastTimestamp);
            long timestamp;
            for (;;) {
                timestamp = this.millisecond();
                System.out.print('+');
                if (timestamp > lastTimestamp) {
                    System.out.print("
    ");
                    return timestamp;
                }
            }
        }
    
        private long millisecond() {
            return System.currentTimeMillis();
        }
    
        public static void main(String[] args) {
            SnowflakeId worker = new SnowflakeId(1);
            long start = System.currentTimeMillis();
            for (int i = 0; i < 5000000; i ++) {
                //System.out.println(worker.nextId());
                worker.nextId();
            }
            long duration = System.currentTimeMillis() - start;
            System.out.println("Total: " + duration + "ms, " + 5000000/duration + "/ms");
        }
    }
  • 相关阅读:
    Liferay 6.2 改造系列之十五:修改默认可用语言
    Liferay 6.2 改造系列之十七:当Portlet无权限时,不显示错误信息
    Liferay 6.2 改造系列之十四:修改组织的表单内容
    Liferay 6.2 改造系列之十三:修改用户编辑页面表单内容
    Liferay 6.2 改造系列之十一:默认关闭CDN动态资源
    matlab向量的排序(自写函数)
    matlab求一个矩阵中各元素出现的个数(归一化)
    matlab求矩阵的鞍点
    matlab求矩阵、向量的模
    matlab求最大公约数和最小公倍数
  • 原文地址:https://www.cnblogs.com/milton/p/5169890.html
Copyright © 2011-2022 走看看