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

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

Java實現雪花算法(snowflake)

瀏覽:22日期: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
相關文章:
主站蜘蛛池模板: ALC墙板_ALC轻质隔墙板_隔音防火墙板_轻质隔墙材料-湖北博悦佳 | 卸料器-卸灰阀-卸料阀-瑞安市天蓝环保设备有限公司 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 手术示教系统-数字化手术室系统-林之硕医疗云智能视频平台 | 安徽成考网-安徽成人高考网 | 膏方加工_丸剂贴牌_膏滋代加工_湖北康瑞生物科技有限公司 | 知网论文检测系统入口_论文查重免费查重_中国知网论文查询_学术不端检测系统 | PC构件-PC预制构件-构件设计-建筑预制构件-PC构件厂-锦萧新材料科技(浙江)股份有限公司 | 杭州网络公司_百度SEO优化-外贸网络推广_抖音小程序开发-杭州乐软科技有限公司 | 酒糟烘干机-豆渣烘干机-薯渣烘干机-糟渣烘干设备厂家-焦作市真节能环保设备科技有限公司 | 冷油器-冷油器换管改造-连云港灵动列管式冷油器生产厂家 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | ASA膜,ASA共挤料,篷布色母料-青岛未来化学有限公司 | 硅PU球场、篮球场地面施工「水性、环保、弹性」硅PU材料生产厂家-广东中星体育公司 | EPDM密封胶条-EPDM密封垫片-EPDM生产厂家 | 北京康百特科技有限公司-分子蒸馏-短程分子蒸馏设备-实验室分子蒸馏设备 | 高压微雾加湿器_工业加湿器_温室喷雾-昌润空气净化设备 | 杭州荣奥家具有限公司-浙江办公家具,杭州办公家具厂 | 大功率金属激光焊接机价格_不锈钢汽车配件|光纤自动激光焊接机设备-东莞市正信激光科技有限公司 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 酒瓶_酒杯_玻璃瓶生产厂家_徐州明政玻璃制品有限公司 | PC构件-PC预制构件-构件设计-建筑预制构件-PC构件厂-锦萧新材料科技(浙江)股份有限公司 | 山东商品混凝土搅拌楼-环保型搅拌站-拌合站-分体仓-搅拌机厂家-天宇 | 氮化镓芯片-碳化硅二极管 - 华燊泰半导体| 不锈钢螺丝 - 六角螺丝厂家 - 不锈钢紧固件 - 万千紧固件--紧固件一站式采购 | 帽子厂家_帽子工厂_帽子定做_义乌帽厂_帽厂_制帽厂_帽子厂_浙江高普制帽厂 | 防水套管|柔性防水套管|伸缩器|伸缩接头|传力接头-河南伟创管道 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | 浙江华锤电器有限公司_地磅称重设备_防作弊地磅_浙江地磅售后维修_无人值守扫码过磅系统_浙江源头地磅厂家_浙江工厂直营地磅 | 带式过滤机厂家_价格_型号规格参数-江西核威环保科技有限公司 | 上海办公室装修公司_办公室设计_直营办公装修-羚志悦装 | 药品冷藏箱厂家_低温冰箱_洁净工作台-济南欧莱博电子商务有限公司官网 | 郑州外墙清洗_郑州玻璃幕墙清洗_郑州开荒保洁-河南三恒清洗服务有限公司 | 有源电力滤波装置-电力有源滤波器-低压穿排电流互感器|安科瑞 | 能量回馈_制动单元_电梯节能_能耗制动_深圳市合兴加能科技有限公司 | 铝板冲孔网,不锈钢冲孔网,圆孔冲孔网板,鳄鱼嘴-鱼眼防滑板,盾构走道板-江拓数控冲孔网厂-河北江拓丝网有限公司 | 上海噪音治理公司-专业隔音降噪公司-中广通环保 | 非标压力容器_碳钢储罐_不锈钢_搪玻璃反应釜厂家-山东首丰智能环保装备有限公司 | 不锈钢水箱厂家,不锈钢保温水箱-山东桑特供水设备 | 拖鞋定制厂家-品牌拖鞋代加工厂-振扬实业中国高端拖鞋大型制造商 | 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 无锡装修装潢公司,口碑好的装饰装修公司-无锡索美装饰设计工程有限公司 | 烽火安全网_加密软件、神盾软件官网 |