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("\n");
                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");
    }
}
复制代码

 

posted on   Milton  阅读(1491)  评论(0编辑  收藏  举报

编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示