工具类: 

package com.ihrm.common.utils;import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;//雪花算法代码实现
public class IdWorker {// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)private final static long twepoch = 1288834974657L;// 机器标识位数private final static long workerIdBits = 5L;// 数据中心标识位数private final static long datacenterIdBits = 5L;// 机器ID最大值private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);// 数据中心ID最大值private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);// 毫秒内自增位private final static long sequenceBits = 12L;// 机器ID偏左移12位private final static long workerIdShift = sequenceBits;// 数据中心ID左移17位private final static long datacenterIdShift = sequenceBits + workerIdBits;// 时间毫秒左移22位private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private final static long sequenceMask = -1L ^ (-1L << sequenceBits);/* 上次生产id时间戳 */private static long lastTimestamp = -1L;// 0,并发控制private long sequence = 0L;private final long workerId;// 数据标识id部分private final long datacenterId;public IdWorker(){this.datacenterId = getDatacenterId(maxDatacenterId);this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);}/*** @param workerId*            工作机器ID* @param datacenterId*            序列号*/public IdWorker(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;}/*** 获取下一个ID** @return*/public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException(String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));}if (lastTimestamp == timestamp) {// 当前毫秒内,则+1sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 当前毫秒内计数满了,则等待下一秒timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;// ID偏移组合生成最终的ID,并返回IDlong nextId = ((timestamp - twepoch) << timestampLeftShift)| (datacenterId << datacenterIdShift)| (workerId << workerIdShift) | sequence;return nextId;}private long tilNextMillis(final long lastTimestamp) {long timestamp = this.timeGen();while (timestamp <= lastTimestamp) {timestamp = this.timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}/*** <p>* 获取 maxWorkerId* </p>*/protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {StringBuffer mpid = new StringBuffer();mpid.append(datacenterId);String name = ManagementFactory.getRuntimeMXBean().getName();if (!name.isEmpty()) {/** GET jvmPid*/mpid.append(name.split("@")[0]);}/** MAC + PID 的 hashcode 获取16个低位*/return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);}/*** <p>* 数据标识id部分* </p>*/protected static long getDatacenterId(long maxDatacenterId) {long id = 0L;try {InetAddress ip = InetAddress.getLocalHost();NetworkInterface network = NetworkInterface.getByInetAddress(ip);if (network == null) {id = 1L;} else {byte[] mac = network.getHardwareAddress();id = ((0x000000FF & (long) mac[mac.length - 1])| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;id = id % (maxDatacenterId + 1);}} catch (Exception e) {System.out.println(" getDatacenterId: " + e.getMessage());}return id;}
}

使用:

IdWorker idWorker = new IdWorker();long id = idWorker.nextId();

生成主键ID,唯一键id,分布式ID生成器雪花算法代码实现相关推荐

  1. springboot 主键重复导致数据重复_程序员:MySQL处理插入过程中主键或唯一键重复值的解决办法

    向MySQL插入数据有时会遇到主键重复的场景,原来的做法是先在程序代码中SELECT一下,判断是否存在指定主键或唯一键的数据,如果没有则插入,有的话则执行UPDATE操作,或另外一套逻辑,这种方法是不 ...

  2. MySQL处理插入过程中主键或唯一键重复值的解决办法

    向MySQL插入数据有时会遇到主键重复的场景,原来的做法是先在程序代码中SELECT一下,判断是否存在指定主键或唯一键的数据,如果没有则插入,有的话则执行UPDATE操作,或另外一套逻辑,这种方法是不 ...

  3. 主键、唯一键、外键、

    类型 保证唯一性 是否允许空 一个表中可以有多少个 是否允许组合 主键(primary key) 是 否 至多一个,可以为0 允许(不推荐,因为不稳定) 唯一(unique) 是 是 可以有多个 允许 ...

  4. mysql唯一性和主键区别_Mysql主键和唯一键的区别点总结

    什么是主键? 主键是表中唯一标识该表中每个元组(行)的列.主键对表实施完整性约束.表中只允许使用一个主键.主键不接受任何重复值和空值.表中的主键值很少更改,因此在选择主键是需要小心,要选择很少发生更改 ...

  5. powerdesigner设置主键为自增字段,设置非主键为唯一键并作为表的外键

    转自:https://www.cnblogs.com/CoffeeHome/archive/2014/06/04/3767501.html 这里powerdesigner连接的数据库是以mysql为例 ...

  6. DB2添加数据时主键、唯一键冲突的解决方法

    DB2添加数据时主键.唯一键冲突的解决方法 参考文章: (1)DB2添加数据时主键.唯一键冲突的解决方法 (2)https://www.cnblogs.com/equation/articles/91 ...

  7. ORA-02437: cannot validate(主键或唯一键约束名) - primary key violated

    今天在对现有表建立唯一索引时遇到该Ora异常 ORA-02437: cannot validate(主键或唯一键约束名) - primary key violated 主键或唯一键的数据有重复值,一般 ...

  8. sql主键和唯一键和外键

    mysql数据库中对字段的约束里存在主键约束,也存在唯一键约束,这两种约束很容易出现混淆的情况,这里讲一下两个的区别: 主键和唯一键的对比: 约束 保证唯一性 是否为空 一个表中有多少个 是否允许组合 ...

  9. MySQL中的主键、唯一键、外键对比

    一.主键 主键:每张表中只能有一个字段(复合主键可以有多个字段)使用此属性,用来唯一约束该字段中的数据,不能重复 1.增加主键: 在创建表的时候,直接在字段后,添加primary key关键字 CRE ...

最新文章

  1. 美妆AI要抢李佳琦的饭碗?
  2. 第四范式受邀参加信息技术大讲堂 共探新基建发展趋势
  3. Angular No provider for EffectsRootModule错误消息的出现原因和修复方式
  4. SAP CRM and C4C PDF print
  5. 奇淫巧技-Flutter调用C#
  6. Tab标签页接口---使用Intent对象
  7. java标识符命名_Java标识符命名规则
  8. Mysql学习总结(63)——Mysql数据库架构方案选择与分析
  9. AndroidStudio安卓原生开发_Fragment_认识使用Fragment_创建_删除fragment---Android原生开发工作笔记116
  10. C# 代码调整屏幕分辨率
  11. Doris之物化视图
  12. 并发编程的挑战——sychronized锁
  13. C语言深度剖析-----数组基础
  14. X1000对于camera控制部分的翻译
  15. Ckeditor富文本编辑器的使用Smartupload文件上传
  16. IC人物志-Intel创世人Robert Norton Noyce(罗伯特·诺伊斯)
  17. linux什么时候挂载根文件系统,什么时候要重新制作Linux的根文件系统?谢谢
  18. Unity UGUI 代码改变遮挡层级
  19. 杭州旭航集团,申请纳斯达克IPO上市,募资9800万美元
  20. 最详细的SQL注入语句

热门文章

  1. 第十周Java学习总结
  2. 12-文本属性和字体属性
  3. Hexo瞎折腾系列(6) - 将博客同时部署到Github和Coding
  4. 批处理-删除环境变量
  5. MM物料移动BW数据源介绍
  6. 位运算 进制转化 STL中bitset用法
  7. 系统分区 ,硬盘格式化,
  8. 1296: [SCOI2009]粉刷匠
  9. 28 个必备的 Linux 命令行工具
  10. linux 0.11 源码学习(十四)