当前位置: 首页 > news >正文

【雪花算法】

雪花算法

package com.shaoby.common.utils;import com.shaoby.common.enums.ExceptionEnum;
import com.shaoby.common.exception.ApiException;import java.time.*;
import java.util.*;
import java.util.concurrent.CountDownLatch;/*** 雪花算法生产64位全局唯一ID* 1位符号位* 41位存储时间戳* 5位存储机器ID* 5位存储服务ID* 12位自增序列号* @Author Cookie* @Date 2024/6/23 1:12*/
public class SnowFlakeUtils {//机器ID,暂时写死private long workerid = 0;//服务ID,暂时写死private long serviceid = 0;//2024-01-01 00:00:00时间戳private final long basicTime = 1704038400000L;//机器ID所占的位数private final long workerIdBits = 5L;//服务ID所占位数private final long serviceBitId = 5L;//机器ID最大值,用于校验机器IDprivate final long maxWorkIdBit = -1 ^ (-1 << workerIdBits);//服务ID最大值,用于校验服务器IDprivate final long maxServiceIdBit = -1 ^ (-1 << serviceBitId);//序列在ID中占的位数private final long sequenceBits = 12L;//机器ID左移12位;private final long workerIdShift = sequenceBits;//服务ID左移17位private final long serviceIdShift = sequenceBits + sequenceBits;//时间戳左移22位private final long timeShift = sequenceBits + sequenceBits + workerIdBits;//毫秒内最大序列号private final long maxSequence = (-1L) ^(-1 << sequenceBits);//毫秒内序列private long sequence = 0L;//上次生成序号时间戳private long lastTimestamp = 0L;public synchronized long getNextId(){//当前时间戳long timestamp = timeGen();//时间回溯抛异常if(timestamp < lastTimestamp){throw new ApiException(ExceptionEnum.TIME_BACK_ERROR);}//如果是毫秒内生成sequence+1if(timestamp == lastTimestamp){/*** 当毫秒内生成的序列号没有超过最大值时候,直接加一,* 如果超过了最大值会溢出,十二位不够存储,比如 1111 1111 1111 1111再加一回多一位变成 1 0000 0000 0000,* 这里这样处理:去 & 上一个最大值,* 如果超过了最大值,即 1 0000 0000 0000 &  1111 1111 1111 变成 0000 0000 0000* 如果没有超过最大值,如 1111 0000 0000 & 1111 1111 1111 还是 1111 0000 0000,不变*/sequence = (sequence+1) & maxSequence;/** 如果为0表示超过了最大值,则放到下一毫秒生成*/if(sequence == 0L){timestamp = nextTimeGen(timestamp);}}else {sequence = 0;}lastTimestamp = timestamp;return ((timestamp-basicTime) << timeShift) | (workerid << workerIdShift) | (serviceid << serviceIdShift) | sequence;}/** 获取当前时间戳*/private long timeGen() {return System.currentTimeMillis();}/** 获取下一毫秒时间戳*/private long nextTimeGen(long time){//拿到当前时间戳long timeStamp = timeGen();//如过还在当前毫秒内,重新获取当前时间,只到拿到非当前毫秒内时间戳while (time <= timeStamp){timeStamp = timeGen();}return timeStamp;}public static void main(String[] args) throws InterruptedException {SnowFlakeUtils snowFlakeUtils = new SnowFlakeUtils();Set<Object> set = Collections.synchronizedSet(new LinkedHashSet<>());int threadCount = 500;CountDownLatch latch = new CountDownLatch(threadCount);for (int i = 0; i < threadCount; i++) {new Thread(() -> {long nextId = snowFlakeUtils.getNextId();System.out.println(Thread.currentThread().getName() +"--->"+ nextId);set.add(nextId);latch.countDown();}).start();}latch.await();System.out.println(set.size());}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • SpringBoot使用spring.factories加载默认配置
  • Python+Pytest+Yaml+Request+Allure接口自动化测试框架详解
  • HTTP网络协议
  • Esxi上创建windows 11虚拟机
  • 一个关于空格的Sql Server面试题
  • shinydashboard与shiny详细教程
  • # Kafka_深入探秘者(2):kafka 生产者
  • 如何让视频有高级感 高级感视频制作方法 高级感视频怎么剪 会声会影视频剪辑制作教程 会声会影中文免费下载
  • [Linux] 文件/目录命令
  • MySQL学习笔记-进阶篇-锁
  • 反射机制详解
  • 6 DSL_03地理信息查询相关性算分
  • std::function和std::bind函数
  • MyBatis-Plus入门教程(一)
  • Day11 —— 大数据技术之Spark
  • 《剑指offer》分解让复杂问题更简单
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  •  D - 粉碎叛乱F - 其他起义
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • exports和module.exports
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • JavaScript对象详解
  • js操作时间(持续更新)
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Markdown 语法简单说明
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • node-glob通配符
  • vue学习系列(二)vue-cli
  • 创建一个Struts2项目maven 方式
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 代理模式
  • 构建二叉树进行数值数组的去重及优化
  • 规范化安全开发 KOA 手脚架
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 如何胜任知名企业的商业数据分析师?
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 深入浏览器事件循环的本质
  • 学习HTTP相关知识笔记
  • 一文看透浏览器架构
  • 最简单的无缝轮播
  • Semaphore
  • 正则表达式-基础知识Review
  • 昨天1024程序员节,我故意写了个死循环~
  • ​​​【收录 Hello 算法】10.4 哈希优化策略
  • #NOIP 2014#Day.2 T3 解方程
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (1)常见O(n^2)排序算法解析
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (floyd+补集) poj 3275
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (十六)Flask之蓝图
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (转)3D模板阴影原理