/**
* ID生成 雪花算法
*/
public class SnowFlake
{
public static SnowFlake getInstance()
{
return SingletonSnowFlake.instance;
} private static class SingletonSnowFlake
{
private static final SnowFlake instance = new SnowFlake(1,1);
} /**
* 起始的时间戳
*/
private final static long START_STMP = 1480166465631L; /**
* 每一部分占用的位数
*/
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
*
* @return
*/
public synchronized long nextId()
{ long currStmp = getNewstmp(); if (currStmp < lastStmp)
{
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
} if (currStmp == lastStmp)
{
//相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE; //同一毫秒的序列数已经达到最大
if (sequence == 0L)
{
currStmp = getNextMill();
}
}
else
{
//不同毫秒内,序列号置为0
sequence = 0L;
} lastStmp = currStmp; return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
} private long getNextMill()
{
long mill = getNewstmp(); while (mill <= lastStmp)
{
mill = getNewstmp();
}
return mill;
} private long getNewstmp()
{
return System.currentTimeMillis();
} public static void main(String[] args)
{
SnowFlake snowFlake = new SnowFlake(1, 1); long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++)
{
System.out.println(snowFlake.nextId());
} System.out.println(System.currentTimeMillis() - start); }
}

ID生成 雪花算法的更多相关文章

  1. 全局ID生成--雪花算法

    分布式ID常见生成策略: 分布式ID生成策略常见的有如下几种: 数据库自增ID. UUID生成. Redis的原子自增方式. 数据库水平拆分,设置初始值和相同的自增步长. 批量申请自增ID. 雪花算法 ...

  2. 分布式ID生成 - 雪花算法

    雪花算法是一种生成分布式全局唯一ID的经典算法,关于雪花算法的解读网上多如牛毛,大多抄来抄去,这里请参考耕耘的小象大神的博客ID生成器,Twitter的雪花算法(Java) 网上的教程一般存在两个问题 ...

  3. 全局ID生成--雪花算法改进版

    存在的问题 时间回拨问题:由于机器的时间是动态的调整的,有可能会出现时间跑到之前几毫秒,如果这个时候获取到了这种时间,则会出现数据重复 机器id分配及回收问题:目前机器id需要每台机器不一样,这样的方 ...

  4. ID 生成器 雪花算法

    https://blog.csdn.net/wangming520liwei/article/details/80843248 ID 生成器 雪花算法 2018年06月28日 14:58:43 wan ...

  5. 分布式ID的雪花算法及坑

    分布式ID生成是目前系统的常见刚需,其中以Twitter的雪花算法(Snowflake)比较知名,有Java等各种语言的版本及各种改进版本,能生成满足分布式ID,返回ID为Long长整数 但是这里有一 ...

  6. 适用于分布式ID的雪花算法

    基于Java实现的适用于分布式ID的雪花算法工具类,这里存一下日后好找 /** * 雪花算法生成ID */ public class SnowFlakeUtil { private final sta ...

  7. 分布式系统-主键唯一id,订单编号生成-雪花算法-SnowFlake

    分布式系统下 我们每台设备(分布式系统-独立的应用空间-或者docker环境) * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作 ...

  8. 全局唯一iD的生成 雪花算法详解及其他用法

    一.介绍 雪花算法的原始版本是scala版,用于生成分布式ID(纯数字,时间顺序),订单编号等. 自增ID:对于数据敏感场景不宜使用,且不适合于分布式场景.GUID:采用无意义字符串,数据量增大时造成 ...

  9. 生成主键ID,唯一键id,分布式ID生成器雪花算法代码实现

    工具类:  package com.ihrm.common.utils; import java.lang.management.ManagementFactory; import java.net. ...

随机推荐

  1. celery异步发送邮件

    利用Django框架发送邮件的详细过程,在前两天的博客中有所记录,但是单纯的那样发邮件是有非常大的问题的,这就需要celery异步发送来解决 首先我们来看一下邮件发送的过程: Django网站先发送到 ...

  2. 如何用纯 CSS 创作出平滑的层叠海浪特效

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/JvmBdE 可交互视频教 ...

  3. pc端和移动端的“窗口”(viewport)故事(part1)

    A tale of two viewports - part one 在以下的系列文章中,我将为大家解释浏览器中的视窗和一些重要的元素的尺寸是如何起作用的,如:大家最熟悉的html元素以及window ...

  4. java构造方法的注意事项总结

    构造方法细节总结~~~~~ 1:首先要了解为什么需要构造方法,,,类中有太多的属性,每次给属性赋值时非常麻烦:编码量大,无法重用给属性赋值的代码.. 2:什么是构造方法呢? 构造方法负责初始化类中的实 ...

  5. 为什么选择器:last-child有时没有起作用?

    想要有.list样式的最后一个不要下划线.为什么:last-child没有起作用? el:last-child 的匹配规则是:第一步,查找 el 选择器匹配元素的所有同级元素(siblings):第二 ...

  6. 富文本编辑器--使用textarea即时更新文本域同步编辑器内容

    使用 textarea wangEditor 从v3版本开始不支持 textarea ,但是可以通过onchange来实现 textarea 中提交富文本内容. <div id="di ...

  7. 使用CLI 3 创建发布Web Components

    本文翻译自:codementor 翻译不当之处,欢迎指正交流 Web Components是web平台的未来吗?关于这一问题支持和反对的观点有很多.事实上浏览器对Web Components的支持正在 ...

  8. 腾讯地图JSAPI开发demo 定位,查询

    1.IP定位切换 2.点击坐标获取地点 3.查询地点切换坐标 <!DOCTYPE html> <html> <head> <meta http-equiv=& ...

  9. 1.device-manage 优化

    一.当前简介 版本信息 device-manage:v1.0 mysql: 5.6.20 jdk : 1.8 Apache Maven 3.3.3 Spring4.2.5.RELEAS+SpingMV ...

  10. js中 base64 转二进制

    function base64toBlob(base64,type) { // 将base64转为Unicode规则编码 let bstr = atob(base64, type), n = bstr ...