怎么实现缩小版雪花算法与多线程并发测试
发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,这篇文章主要讲解了"怎么实现缩小版雪花算法与多线程并发测试",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么实现缩小版雪花算法与多线程并发测试"吧!我
千家信息网最后更新 2025年01月21日怎么实现缩小版雪花算法与多线程并发测试
这篇文章主要讲解了"怎么实现缩小版雪花算法与多线程并发测试",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么实现缩小版雪花算法与多线程并发测试"吧!
我们设计数据表的时候,一般都会有ID字段,ID的生成方法有多种,比如数据库自增,UUID,雪花算法等。
考虑到以后数据的增长,分库分表,分布式等要求,我们选择雪花算法来生成ID。
开发Web系统需要后端跟前端交互,前端JavaScript支持的最大整型是53位,超过53位会丢失精度,原版的雪花算法会超过53位,我们使用缩小版的雪花算法,把位数减小到53位。
原版Snowflake算法的极限是每毫秒的每一个节点生成4059个id值,也就是说每毫秒的极限是生成023*4059=4 152 357个id值 ,缩小后极限是每秒生成15*131071=1 966 065个分布式id,够我们在开发里面的日常使用了。
package cn.gintone.asso.util;/** * @description:缩小版的雪花算法 * @author:Elon He * @create:2020-10-06 */public class SnowflakeMini { /** * 开始时间截 (1970-01-01) */ private final static long twepoch = 0L; /** * 机器id,范围是1到15 */ private final static long workerId =1L; /** * 机器id所占的位数,占4位 */ private final static long workerIdBits = 4L; /** * 支持的最大机器id,结果是15 */ private final static long maxWorkerId = ~(-1L << workerIdBits); /** * 生成序列占的位数 */ private final static long sequenceBits = 15L; /** * 机器ID向左移15位 */ private final static long workerIdShift = sequenceBits; /** * 生成序列的掩码,这里为最大是32767 (1111111111111=32767) */ private final static long sequenceMask = ~(-1L << sequenceBits); /** * 时间截向左移19位(4+15) */ private final static long timestampLeftShift = 19L; /** * 秒内序列(0~32767) */ private static long sequence = 0L; /** * 上次生成ID的时间截 */ private static long lastTimestamp = -1L; /** * 获得下一个ID (该方法是线程安全的) * * @return SnowflakeId */ public static 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; //黄色代码注释开始 //移位并通过或运算拼到一起组成53 位的ID return ((timestamp - twepoch) << timestampLeftShift) | (workerId << workerIdShift) | sequence; //黄色代码注释结束 } /** * 阻塞到下一个秒,直到获得新的时间戳 * * @param lastTimestamp 上次生成ID的时间截 * @return 当前时间戳 */ protected static long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } /** * 返回以秒为单位的当前时间 * * @return 当前时间(秒) */ protected static long timeGen() { return System.currentTimeMillis()/1000L; }}
创建两个线程,同时测试ID获取。
测试线程类A
package cn.gintone.asso;import cn.gintone.asso.util.SnowflakeMini;/** * @description:线程A * @author:Elon He * @create:2020-10-06 */public class ThreadA extends Thread{ @Override public void run() { super.run(); for (int i = 0; i < 10; i++) { long id = SnowflakeMini.nextId(); System.out.println("A:"+id); } }}
测试线程类B
package cn.gintone.asso;import cn.gintone.asso.util.SnowflakeMini;/** * @description:线程B * @author:Elon He * @create:2020-10-06 */public class ThreadB extends Thread{ @Override public void run() { super.run(); for (int i = 0; i < 10; i++) { long id = SnowflakeMini.nextId(); System.out.println("B:"+id); } }}
测试类(注释掉的代码是修改成静态方法前的测试方法)
package cn.gintone.asso;/** * @description:雪花算法测试类 * @author:Elon He * @create:2020-10-06 */public class TestSnowflake { public static void main(String[] args) { //不同线程使用同一个对象,不重复// SnowflakeMini idWorker = new SnowflakeMini(0);// ThreadA t1 = new ThreadA(idWorker);// ThreadB t2 = new ThreadB(idWorker);// t1.start();// t2.start(); //不同线程使用不同对象,会重复// SnowflakeMini idWorker1 = new SnowflakeMini(0);// SnowflakeMini idWorker2 = new SnowflakeMini(0);// ThreadA t1 = new ThreadA(idWorker1);// ThreadB t2 = new ThreadB(idWorker2);// t1.start();// t2.start(); //nextId修改成静态方法后测试,不重复 ThreadA t1 = new ThreadA(); ThreadB t2 = new ThreadB(); t1.start(); t2.start(); }}
测试结果
感谢各位的阅读,以上就是"怎么实现缩小版雪花算法与多线程并发测试"的内容了,经过本文的学习后,相信大家对怎么实现缩小版雪花算法与多线程并发测试这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
时间
线程
测试
生成
算法
雪花
代码
注释
序列
方法
机器
不同
最大
位数
数据
极限
学习
内容
分布式
前端
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
ns暗黑2登录不上服务器
我的世界基岩版服务器多人生存
c操作access数据库
关于网络文明网络安全的征文
网易邮箱依据网络安全法
国家外语数据库
数据库怎么区分测试数据
软件开发费用一年多少钱
手机服务器设置视频
小型局域网网络技术选型
目前我国软件开发公司
鹰潭企业服务器大概费用
网络安全小课堂网络社交
Dgs升级后数据库丢失
巴比塔网络技术股份
sqlyog数据库管理软件
查询数据库数据时间很才
上海守时模块服务器
戴尔服务器的优点
北京应用软件开发教程
语音服务器有window
数据库怎么区分测试数据
朝阳小学国家网络安全宣传周活动
数据库oracle开发
如何运营软件开发服务公司
数据库分享论坛
手机控制阿里云服务器
软件开发升级途径
网络安全等级保护简要介绍
查询数据库表的数量