Twitter-Snowflake主键算法Java实现

这一篇理论的东西就不解释了,直接上代码,有兴趣的可以看上另一篇文章:数据库分库分表(一)常见分布式主键ID生成策略

package util;

/**
 * Twitter-snowflake负载均衡主键算法
 * 共分成4段:
 * 1.符号位( 1bit)
 * 2.时间戳(41bit):计算下来能够使用的期限为:2039-09-07 23:47:35.551,如果希望支持更久,将参考时间1970-01-01换成其它时间
 * 3.主机号(10bit):
 * 4.序列号(12bit):1毫秒内单机的并发最大为4096,超过4096则只能等待下一毫秒
 */

public class SnowflakeGenerator {
    //时间戳二进制位数
//    private final static int TIMESTAMP_BITS = 41;
    //主机号二进制位数
    private final static int SERVER_NODE_BITS = 10;
    //序列号二进制位数
    private final static int SEQUENCE_BITS = 12;


    //主机号:0~2**10-1
    private final static int MAX_SERVER_NODE = 1024;
    //序列号:0~2**12-1
    private final static int MAX_SEQUENCE = 4096;

    //当前主机节点[0,1024)
    private static int serverNode = 0;

    //序列号
    private static int sequence = 0;

    //上次生成id的时间
    private static long previousTimestamp = -1L;

    /**
     * 生成唯一主键
     * @return 64位long类型主键
     */
    public static synchronized long generate(int node){
        //初始化Snowflake主键生成器
        if (node < 0 || node >= MAX_SERVER_NODE) {
            throw new IllegalArgumentException(String.format("主机节点号范围为[%s and %s)", 0, MAX_SERVER_NODE));
        }
        serverNode = node;

        long timestamp;
        timestamp = System.currentTimeMillis();
        if(timestamp>previousTimestamp){
            sequence=0;
            previousTimestamp=timestamp;
        }else if(timestamp==previousTimestamp){
            if(++sequence==MAX_SEQUENCE){
                //序列号已到最大值,重置为0,此毫秒内不能再生成id,只能等下一毫秒
                sequence=0;
                timestamp=nextMillisecond();
                previousTimestamp=timestamp;
            }
        }else{
            throw new RuntimeException(String.format("当前时间戳 %s 小于 上次时间戳 %s",timestamp,previousTimestamp));
        }
        return timestamp<

你可能感兴趣的:(Twitter-Snowflake主键算法Java实现)