电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Java實現雪花算法(snowflake)

瀏覽:21日期:2022-08-26 09:20:50

本文主要介紹了Java實現雪花算法(snowflake),分享給大家,具體如下:

Java實現雪花算法(snowflake)

簡單描述

最高位是符號位,始終為0,不可用。

41位的時間序列,精確到毫秒級,41位的長度可以使用69年。時間位還有一個很重要的作用是可以根據時間進行排序。注意,41位時間截不是存儲當前時間的時間截,而是存儲時間截的差值(當前時間截 - 開始時間截) 后得到的值,這里的的開始時間截,一般是我們的id生成器開始使用的時間,由我們程序來指定的(如下下面程序SnowFlake類的START_STMP屬性)。41位的時間截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69 10位的機器標識,10位的長度最多支持部署1024個節點。 12位的計數序列號,序列號即一系列的自增id,可以支持同一節點同一毫秒生成多個ID序號,12位的計數序列號支持每個節點每毫秒產生4096個ID序號。

加起來剛好64位,為一個Long型。這個算法很簡潔,但依舊是一個很好的ID生成策略。其中,10位器標識符一般是5位IDC+5位machine編號,唯一確定一臺機器。

算法實現

public class SnowFlake { // 起始的時間戳 private final static long START_STMP = 1577808000000L; //2020-01-01 // 每一部分占用的位數,就三個 private final static long SEQUENCE_BIT = 12; //序列號占用的位數 private final static long MACHINE_BIT = 5; //機器標識占用的位數 private final static long DATACENTER_BIT = 5; //數據中心占用的位數 // 每一部分最大值 private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT); private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT); private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); // 每一部分向左的位移 private final static long MACHINE_LEFT = SEQUENCE_BIT; private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT; private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT; private long datacenterId; //數據中心 private long machineId; //機器標識 private long sequence = 0L; //序列號 private long lastStmp = -1L; //上一次時間戳 public SnowFlake(long datacenterId, long machineId) { if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) { throw new IllegalArgumentException('datacenterId can’t be greater than MAX_DATACENTER_NUM or less than 0'); } if (machineId > MAX_MACHINE_NUM || machineId < 0) { throw new IllegalArgumentException('machineId can’t be greater than MAX_MACHINE_NUM or less than 0'); } this.datacenterId = datacenterId; this.machineId = machineId; } //產生下一個ID public synchronized long nextId() { long currStmp = timeGen(); if (currStmp < lastStmp) { throw new RuntimeException('Clock moved backwards. Refusing to generate id'); } if (currStmp == lastStmp) { //if條件里表示當前調用和上一次調用落在了相同毫秒內,只能通過第三部分,序列號自增來判斷為唯一,所以+1. sequence = (sequence + 1) & MAX_SEQUENCE; //同一毫秒的序列數已經達到最大,只能等待下一個毫秒 if (sequence == 0L) { currStmp = getNextMill(); } } else { //不同毫秒內,序列號置為0 //執行到這個分支的前提是currTimestamp > lastTimestamp,說明本次調用跟上次調用對比,已經不再同一個毫秒內了,這個時候序號可以重新回置0了。 sequence = 0L; } lastStmp = currStmp; //就是用相對毫秒數、機器ID和自增序號拼接 return (currStmp - START_STMP) << TIMESTMP_LEFT //時間戳部分 | datacenterId << DATACENTER_LEFT //數據中心部分 | machineId << MACHINE_LEFT //機器標識部分 | sequence;//序列號部分 } private long getNextMill() { long mill = timeGen(); while (mill <= lastStmp) { mill = timeGen(); } return mill; } private long timeGen() { return System.currentTimeMillis(); }}

當增加一秒生成ID的時候就是增加10位的機器標識+12位序列+約2的10次方(1000毫秒),最終就是增加一個2的32次方4 294 967 296就是42億左右

但是這里有一個坑,雪花算法產生的長整數的精度可能超過javascript能表達的精度,這會導致js獲取的id與雪花算法算出來的id不一致,如雪花算法得到的是36594866121080832,但是因為javascript丟失精度后只獲取到36594866121080830, 這會導致對數據的所有操作都失效。

解決辦法:后端的語言獲取到雪花算法的id后將其轉換為String類型,這樣js也會當做字符串來處理,就不會丟失精度了。

配置方法

@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Autowired public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(toStringConverter()); } /** * BigDecimal Long 轉化為String * * @return */ @Bean public MappingJackson2HttpMessageConverter toStringConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(BigDecimal.class, BigDecimalToStringSerializer.instance); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); simpleModule.addSerializer(long.class, ToStringSerializer.instance); mapper.registerModule(simpleModule); // Include.Include.ALWAYS 默認 // Include.NON_DEFAULT 屬性為默認值不序列化 // Include.NON_EMPTY 屬性為 空('') 或者為 NULL 都不序列化,則返回的json是沒有這個字段的。這樣對移動端會更省流量 // Include.NON_NULL 屬性為NULL 不序列化 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);// 允許出現特殊字符和轉義符 mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); // 允許出現單引號 converter.setObjectMapper(mapper); return converter; } @JacksonStdImpl static class BigDecimalToStringSerializer extends ToStringSerializer { public final static BigDecimalToStringSerializer instance = new BigDecimalToStringSerializer(); public BigDecimalToStringSerializer() { super(Object.class); } public BigDecimalToStringSerializer(Class<?> handledType) { super(handledType); } @Override public boolean isEmpty(SerializerProvider prov, Object value) { if (value == null) { return true; } String str = ((BigDecimal) value).stripTrailingZeros().toPlainString(); return str.isEmpty(); } @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeString(((BigDecimal) value).stripTrailingZeros().toPlainString()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return createSchemaNode('string', true); } @Override public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException { // no type info, just regular serialization serialize(value, gen, provider); } }}

到此這篇關于Java實現雪花算法(snowflake)的文章就介紹到這了,更多相關Java 雪花算法內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 真空泵维修保养,普发,阿尔卡特,荏原,卡西亚玛,莱宝,爱德华干式螺杆真空泵维修-东莞比其尔真空机电设备有限公司 | 环球周刊网| 渗透仪-直剪仪-三轴仪|苏州昱创百科 | 领袖户外_深度旅游、摄影旅游、小团慢旅行、驴友网 | TwistDx恒温扩增-RAA等温-Jackson抗体-默瑞(上海)生物科技有限公司 | 压缩空气检测_气体_水质找上海京工-服务专业、价格合理 | 清水混凝土修复_混凝土色差修复剂_混凝土色差调整剂_清水混凝土色差修复_河南天工 | 废旧物资回收公司_广州废旧设备回收_报废设备物资回收-益美工厂设备回收公司 | 福州甲醛检测-福建室内空气检测_环境检测_水质检测-福建中凯检测技术有限公司 | 瓶盖扭矩测试仪-瓶盖扭力仪-全自动扭矩仪-济南三泉中石单品站 | 工作服定制,工作服定做,工作服厂家-卡珀职业服装(苏州)有限公司 | 热镀锌槽钢|角钢|工字钢|圆钢|H型钢|扁钢|花纹板-天津千百顺钢铁贸易有限公司 | 找培训机构_找学习课程_励普教育 | 快速门厂家-快速卷帘门-工业快速门-硬质快速门-西朗门业 | 芜湖厨房设备_芜湖商用厨具_芜湖厨具设备-芜湖鑫环厨具有限公司 控显科技 - 工控一体机、工业显示器、工业平板电脑源头厂家 | 包装机_厂家_价格-山东包装机有限公司 | 污水处理设备维修_污水处理工程改造_机械格栅_过滤设备_气浮设备_刮吸泥机_污泥浓缩罐_污水处理设备_污水处理工程-北京龙泉新禹科技有限公司 | 九爱图纸|机械CAD图纸下载交流中心 | 铝镁锰板厂家_进口钛锌板_铝镁锰波浪板_铝镁锰墙面板_铝镁锰屋面-杭州军晟金属建筑材料 | 膏剂灌装旋盖机-眼药水灌装生产线-西林瓶粉剂分装机-南通博琅机械科技 | 波纹补偿器_不锈钢波纹补偿器_巩义市润达管道设备制造有限公司 | 压缩空气检测_气体_水质找上海京工-服务专业、价格合理 | 免费B2B信息推广发布平台 - 推发网| 政府回应:200块在义乌小巷能买到爱情吗?——揭秘打工族省钱约会的生存智慧 | 重庆小面培训_重庆小面技术培训学习班哪家好【终身免费复学】 | 胶辊硫化罐_胶鞋硫化罐_硫化罐厂家-山东鑫泰鑫智能装备有限公司 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 通信天线厂家_室分八木天线_对数周期天线_天线加工厂_林创天线源头厂家 | 高速龙门架厂家_监控杆_多功能灯杆_信号灯杆_锂电池太阳能路灯-鑫世源照明 | 低压载波电能表-单相导轨式电能表-华邦电力科技股份有限公司-智能物联网综合管理平台 | 压片机_高速_单冲_双层_花篮式_多功能旋转压片机-上海天九压片机厂家 | 小程序开发公司-小程序制作-微信小程序开发-小程序定制-咏熠软件 | 万烁建筑设计院-建筑设计公司加盟,设计院加盟分公司,市政设计加盟 | 散热器-电子散热器-型材散热器-电源散热片-镇江新区宏图电子散热片厂家 | VI设计-LOGO设计公司-品牌设计公司-包装设计公司-导视设计-杭州易象设计 | 北京亦庄厂房出租_经开区产业园招商信息平台 | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | Honsberg流量计-Greisinger真空表-气压计-上海欧臻机电设备有限公司 | 博莱特空压机|博莱特-阿特拉斯独资空压机品牌核心代理商 | 定制防伪标签_防伪标签印刷_防伪标签厂家-510品保防伪网 | 众品地板网-地板品牌招商_地板装修设计_地板门户的首选网络媒体。 |