java雪花算法工具类-程序员宅基地

技术标签: java  

创建一个SnowFlake的工具类,然后把下面的代码粘过去就可以了


    /**
     * Twitter_Snowflake<br>
     * SnowFlake的结构如下(每部分用-分开):<br>
     * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 -
     * 000000000000 <br>
     * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
     * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
     * 得到的值),这里的的开始时间截
     * ,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。
     * 41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
     * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
     * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
     * 加起来刚好64位,为一个Long型。<br>
     * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,
     * SnowFlake每秒能够产生26万ID左右。
     */

    // ==============================Fields===========================================
    /** 开始时间截 (2015-01-01) */
    private static final long twepoch = 1420041600000L;

    /** 机器id所占的位数 */
    private static final long workerIdBits = 5L;

    /** 数据标识id所占的位数 */
    private static final long datacenterIdBits = 5L;

    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
    private static final long maxWorkerId = -1L ^ (-1L << workerIdBits);

    /** 支持的最大数据标识id,结果是31 */
    private static final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

    /** 序列在id中占的位数 */
    private static final long sequenceBits = 12L;

    /** 机器ID向左移12位 */
    private static final long workerIdShift = sequenceBits;

    /** 数据标识id向左移17位(12+5) */
    private static final long datacenterIdShift = sequenceBits + workerIdBits;

    /** 时间截向左移22位(5+5+12) */
    private static final long timestampLeftShift = sequenceBits + workerIdBits
            + datacenterIdBits;

    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
    private  static final long sequenceMask = -1L ^ (-1L << sequenceBits);

    /** 工作机器ID(0~31) */
    private static long workerId;

    /** 数据中心ID(0~31) */
    private static long datacenterId;

    /** 毫秒内序列(0~4095) */
    private static long sequence = 0L;

    /** 上次生成ID的时间截 */
    private static long lastTimestamp = -1L;

    // ==============================Constructors=====================================
    /**
     * 构造函数
     *
     * @param workerId
     *            工作ID (0~31)
     * @param datacenterId
     *            数据中心ID (0~31)
     */
    public SnowFlake(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));
        }
        SnowFlake.workerId = workerId;
        SnowFlake.datacenterId = datacenterId;
    }

    // ==============================Methods==========================================
    /**
     * 获得下一个ID (该方法是线程安全的)
     *
     * @return SnowflakeId
     */
    public static synchronized long nextId() {
    
        long timestamp = timeGen();

        // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
        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;
        }

        // 上次生成ID的时间截
        lastTimestamp = timestamp;

        // 移位并通过或运算拼到一起组成64位的ID
        return ((timestamp - twepoch) << timestampLeftShift) //
                | (datacenterId << datacenterIdShift) //
                | (workerId << workerIdShift) //
                | sequence;
    }

    /**
     * 阻塞到下一个毫秒,直到获得新的时间戳
     *
     * @param lastTimestamp
     *            上次生成ID的时间截
     * @return 当前时间戳
     */
    protected static long tilNextMillis(long lastTimestamp) {
    
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
    
            timestamp = timeGen();
        }
        return timestamp;
    }

    /**
     * 返回以毫秒为单位的当前时间
     *
     * @return 当前时间(毫秒)
     */
    protected static long timeGen() {
    
        return System.currentTimeMillis();
    }

    public SnowFlake() {
    
        this(0, 0);
    }

    // 生成id
    public static String getId() {
    
        return String.valueOf(SnowFlake.nextId());
    }

    // ==============================Test=============================================
    /** 测试 */
    public static void main(String[] args) {
    
        System.out.println(SnowFlake.nextId());
    }

注:本文为转载文章,因为转载的人太多了,并且都没有标注出原作者,所以原创作者无从考究。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42236784/article/details/117550405

智能推荐

Linux学习之网络相关命令_nc -u 172.0.0.1 12345-程序员宅基地

文章浏览阅读965次。strace、traceroute、tracert、sar、ifconfig、ip、nc、lsof、stat、netstat、ps、pstree、ss、telnet、top、Htop、iotop、powertop、iftop、dstat、nethogs、Nmon、vnstat、host、dig、route、tcpdump_nc -u 172.0.0.1 12345

/etc/hosts.conf_/etc/host.conf-程序员宅基地

文章浏览阅读2.6k次。作用指定如何解析主机域名,可设置网络安全。默认文件内容默认情况,/etc/hosts.conf 文件有如下内容 order hosts,bind multi on12参数说明order是解析顺序的参数,order hosts,bind,nis ,说明先查询解析/etc/hosts文件,然后DNS,再是NIS。multi表示是否运行/etc/hosts文件允许主机指定多个多个地址 ,multi on表示运行。nospoof是否允许服务器对ip地址进行其欺骗,nospoof on表_/etc/host.conf

工业机器人四大家族(ABB、库卡、安川)全套资料,欢迎下载!_abb机器人 panbaidu com-程序员宅基地

文章浏览阅读7.1k次,点赞7次,收藏10次。自1954年世界上第一台机器人诞生以来,世界工业发达国家已经建立起完善的工业机器人产业体系。日本、德国的工业机器人水平全球领先,“四大家族”(ABB、库卡、发那科、安川)为全球主要的工业机器人供应商,占据全球约50%的市场份额,这主要因为他们具备先发优势和技术沉淀。 图表1:全球工业机器人“四大家族”介绍随着我国工业自动化、智能化的发展加速,工业机器人的应用普及也带来了市场的急剧增长。既然在中国机..._abb机器人 panbaidu com

Linux基础命令(常用基本操作命令 管道 重定向 grep)_输入重定向命令,首先输入grep ipv6 /etc/*,观察结果,然后将此命令的输出信息-程序员宅基地

文章浏览阅读410次。终端命令格式command [-option] [parameter]command :命令option : 选项parameter:参数查阅命令帮助信息command –help : 帮助信息man command: Linux手册中函数的具体使用通配符* :任意个数字符? :至少一个字符[] :字符组 [abc][a-f]自动补全..._输入重定向命令,首先输入grep ipv6 /etc/*,观察结果,然后将此命令的输出信息

ultraedit高亮显示verilog文件_verilog.uew-程序员宅基地

文章浏览阅读9.5k次,点赞4次,收藏14次。1、下载文件到官网下载Verilog的语法高亮文件,链接如下:http://www.ultraedit.com/index.php?name=Content&pa=showpageπd=40#wordfiles2、文件配置将下载到的“verilog.uew”放到ulteaedit安装路径下的wordfiles文件夹内,以及C:\Documents and Setti_verilog.uew

黑马程序员---IO流二_记录一个程序运行的次数,当满足指定次数,改程序就不可以再继续运行了-程序员宅基地

文章浏览阅读941次。1. 字符流----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------3.1 概念:计算机不区分二进制文件与文本文件。所有的文件都是以二进制形式存储的,因此,从本质上说,所以的文件都是二进制文件。所以字符流是建立在字节流之上,它能够提供字符层次的编码和解码。在写入一个字符时,Java虚拟机会将字符_记录一个程序运行的次数,当满足指定次数,改程序就不可以再继续运行了

随便推点

什么是低音炮,低音炮的原理与音效-程序员宅基地

文章浏览阅读1.2k次。什么是低音炮,低音炮的原理与音效2011-06-15 15:16 低音炮是大家的一个俗称或者简称,严格讲应该是:同轴喇叭,高音仔,超高音,超重低音。就人耳可闻的音频分析而言,由超重低音、低音、低中音、中音、中高音、高音、超高音等组成。 ..._音效是控制低音炮的原理

TypeSDK总体设计思路和架构-程序员宅基地

文章浏览阅读2.1k次。引言:本文旨在提供读者制作一个自己的聚合SDK的思路,抛砖引玉,让更多的读者对聚合SDK有好的理解。 这是最好的时代,这是最坏的时代,这是智慧的时代,这是愚蠢的时代;这是信仰的时期,这是怀疑的时期;这是光明的季节,这是黑暗的季节;这是希望之春,这是失望之冬;人们面前有着各样事物,人们面前一无所有;人们正在直登天堂;人们正在直下地狱。——《双城记》 双城记的开头,正是_typesdk

keras第一个例程mnist_mlp.py解读-程序员宅基地

文章浏览阅读6.4k次。装好keras后,马上运行了例程minst_mlp.py,哇好牛逼,准确率98.4%,但是并不知道自己干了啥。好吧,啃代码。 1. 开头就懵了,数据集在哪呐。 好,从这句入手,找到mnist.py, 从网上下载了minst.pkl.gz,自己顺手下了下来,解压,打开,,,然而并看不懂。肿么办? 不怕,看这里:机器学习–读取mnist数据集 对于这个数据集的详情也可以参考这里:THE_mnist_mlp.py

Solidity 从入门到实战(三)_remix 转账-程序员宅基地

文章浏览阅读1.7k次,点赞3次,收藏8次。Solidity 从入门到实战(三)注意:本专栏主要来自于https://www.bilibili.com/video/BV1St411a7Pk?p=11&spm_id_from=pageDriver的学习笔记以及https://blog.csdn.net/weixin_45067603/article/details/105751748以太坊中的地址1.以太坊中的地址以40位的16进制表示,储存以uint160进行存储2.地址之间支持大小比较、3.可以分为外部账户地址和合约地址_remix 转账

工具:VMware虚拟机各种后缀文件总结_.vmem-程序员宅基地

文章浏览阅读5.6k次,点赞7次,收藏20次。一、文件介绍.log日志文件。这个文件记录了VMwareWorkstation对虚拟机调节运行的情况,记录虚拟机操作,可用了故障诊断。.vmdk这是一个虚拟磁盘文件,它储存了虚拟机硬盘驱动器里的内容。一台虚拟机可以由一个或几个虚拟磁盘文件组成。如果你已经特别指定了虚拟磁盘每2GB为一单独文件的话,虚拟磁盘的大小就决定了虚拟磁盘文件的数量。随着数据写入虚拟磁盘,虚拟磁盘文件将变大,直到这些文件为2GB。(如果你在创建虚拟磁盘时已经把所有的空间都分配了,那么这些文件将在初始时就具..._.vmem

C语言——死亡游戏_今天她玩了一个新游戏,发现每次死亡后角色的金币都会掉落,假设角色开局有g个金币,-程序员宅基地

文章浏览阅读1.3k次,点赞5次,收藏18次。问题描述:据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus和他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。请你编写一个函数,计算一下Josephus 和他的朋友应该安排在什么位置,才能免于一死(最后剩下他们两人)。【要求人的总数与报数均由键_今天她玩了一个新游戏,发现每次死亡后角色的金币都会掉落,假设角色开局有g个金币,

推荐文章

热门文章

相关标签