package com.gblfy;/*** @Author:JCccc* @Description:* @Date: created in 15:31 2019/6/12*/
public class SnowflakeIdUtils {// ==============================Fields===========================================/** 开始时间截 (2015-01-01) */private final long twepoch = 1420041600000L;/** 机器id所占的位数 */private final long workerIdBits = 5L;/** 数据标识id所占的位数 */private final long datacenterIdBits = 5L;/** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */private final long maxWorkerId = -1L ^ (-1L << workerIdBits);/** 支持的最大数据标识id,结果是31 */private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);/** 序列在id中占的位数 */private final long sequenceBits = 12L;/** 机器ID向左移12位 */private final long workerIdShift = sequenceBits;/** 数据标识id向左移17位(12+5) */private final long datacenterIdShift = sequenceBits + workerIdBits;/** 时间截向左移22位(5+5+12) */private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;/** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */private final long sequenceMask = -1L ^ (-1L << sequenceBits);/** 工作机器ID(0~31) */private long workerId;/** 数据中心ID(0~31) */private long datacenterId;/** 毫秒内序列(0~4095) */private long sequence = 0L;/** 上次生成ID的时间截 */private long lastTimestamp = -1L;//==============================Constructors=====================================/*** 构造函数* @param workerId 工作ID (0~31)* @param datacenterId 数据中心ID (0~31)*/public SnowflakeIdUtils(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;}// ==============================Methods==========================================/*** 获得下一个ID (该方法是线程安全的)* @return SnowflakeId*/public 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位的IDreturn ((timestamp - twepoch) << timestampLeftShift) //| (datacenterId << datacenterIdShift) //| (workerId << workerIdShift) //| sequence;}/*** 阻塞到下一个毫秒,直到获得新的时间戳* @param lastTimestamp 上次生成ID的时间截* @return 当前时间戳*/protected long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}/*** 返回以毫秒为单位的当前时间* @return 当前时间(毫秒)*/protected long timeGen() {return System.currentTimeMillis();}//==============================Test=============================================/** 测试 */public static void main(String[] args) {SnowflakeIdUtils idWorker = new SnowflakeIdUtils(3, 1);System.out.println(idWorker.nextId());}
}

JAVA 雪花算法 唯一ID生成工具类相关推荐

  1. Java:二维码生成工具类

    java 二维码生成工具类 需要引入的maven <!--Java 生成二维码 --> <dependency><groupId>com.google.zxing& ...

  2. java id主键_JAVA主键ID生成工具类:改自twitter的分布式ID算法snowflake

    祝大家新年快乐,有任何问题可与我联系: 关于snowflake算法的介绍和原理这里不过多说明了,网上有很多. 这里简单描述下SnowflakeUtil的优点: 1.做为底层工具使用,可用于数据库主键. ...

  3. Java实现一个单号生成工具类

    在项目开发的过程中,如果一个系统存在多种不同类型的单据,单号生成就比较难以处理,为此,创造出一个单号生成的工具类就很有必要.直接上代码: 实体类:(数据库字段同下) public class Seri ...

  4. 流加密算法之Java RC4算法应用 附可用工具类

    欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!   RC4算法简介(来源于百度百科)   RC4是密钥长度可变的流加密算法簇.RC4是一种在电子信息领域加密的技术手段,用于无线通信网络,是 ...

  5. JAVA 16位ID生成工具类含16位不重复的随机数数字+大小写

    package com.fty.util;import java.security.SecureRandom; import java.util.Random; import java.util.co ...

  6. SpringBoot实战:设备唯一ID生成【雪花算法、分布式应用】

    目录 SpringBoot实战:设备唯一ID生成[雪花算法.分布式应用] 背景: snowflake(雪花算法)方案: 实现: 雪花算法生成ID: 二维码打包: 多线程优化-批量插入: 二维码识别+扫 ...

  7. java 唯一id生成算法_唯一ID生成算法剖析

    在业务开发中,大量场景需要唯一ID来进行标识:用户需要唯一身份标识:商品需要唯一标识:消息需要唯一标识:事件需要唯一标识-等等,都需要全局唯一ID,尤其是分布式场景下. 唯一ID有哪些特性或者说要求呢 ...

  8. Java秒杀系统实战系列~分布式唯一ID生成订单编号

    摘要: 本篇博文是"Java秒杀系统实战系列文章"的第七篇,在本博文中我们将重点介绍 "在高并发,如秒杀的业务场景下如何生成全局唯一.趋势递增的订单编号",我们 ...

  9. java 唯一编号_Java秒杀系统实战系列~分布式唯一ID生成订单编号

    摘要: 本篇博文是"Java秒杀系统实战系列文章"的第七篇,在本博文中我们将重点介绍 "在高并发,如秒杀的业务场景下如何生成全局唯一.趋势递增的订单编号",我们 ...

最新文章

  1. Swing基础知识(更新中)
  2. R语言ggplot2可视化分面图(faceting)、并设置每一个分面中的条形图都是排序的(bars are in order in each per facet of facet_warp)
  3. nginx php-fpm 运行原理
  4. PHP通过Thrift操作Hbase
  5. 正则替换让一部分内容保持不变
  6. LeetCode 第 197 场周赛(468/5273,前8.88%)
  7. 华为智慧屏鸿蒙挂安卓9,荣耀先行!华为智慧屏9月发布:搭鸿蒙系统和自研芯片...
  8. 【Hbase】报错org.apache.hadoop.hbase.RegionTooBusyException
  9. Leetcode每日一题:1002.find-common-characters(查找常用字符串)
  10. 如何在Mac电脑上自定义Spotlight的搜索结果?
  11. easypr4android,EasyPR的基本使用
  12. 一个Python开源项目-哈勃沙箱源码剖析(下)
  13. html5音乐播放器网页底部,jQuery+html5网页底部固定mp3音乐播放器代码
  14. kaldi 的安装和thchs30语音识别测试
  15. python爬表情包_教你用Python来爬取表情包网站的所有表情图片
  16. spring cloud 资源服务器授权配置
  17. 【java】org.xml.sax.SAXParseException;在实体引用中, 实体名称必须紧跟在 '' 后面。解决方法
  18. 海量数据处理方法总结 常见大数据题目汇总
  19. 支付宝小程序申请支付宝公钥遇到的坑
  20. dll名称相同引发的奇葩问题

热门文章

  1. 南大用“推荐算法”分宿舍666,新生配好舍友美滋滋
  2. zedgraph使用中的难题
  3. PHP 循环引用的问题
  4. 二叉查找树 java代码实现
  5. 算术表达式的前缀式、中缀式、后缀式相互转换
  6. Datastream 开发打包问题
  7. 数字营销行业大数据平台云原生升级实战
  8. 可动态调节参数的线程池实现
  9. PyFlink + 区块链?揭秘行业领头企业 BTC.com 如何实现实时计算
  10. 年度回顾 | 2019 年的 Apache Flink