博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 实现的SnowFlake生成UUID (Java代码实战-007)
阅读量:5773 次
发布时间:2019-06-18

本文共 3795 字,大约阅读时间需要 12 分钟。

 SnowFlake所生成的ID一共分成四部分:

1.第一位

占用1bit,其值始终是0,没有实际作用。

2.时间戳

占用41bit,精确到毫秒,总共可以容纳约69 年的时间。

3.工作机器id

占用10bit,其中高位5bit是数据中心ID(datacenterId),低位5bit是工作节点ID(workerId),做多可以容纳1024个节点。

4.序列号

占用12bit,这个值在同一毫秒同一节点上从0开始不断累加,最多可以累加到4095。

SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢?只需要做一个简单的乘法:

同一毫秒的ID数量 = 1024 X 4096 = 4194304

这个数字在绝大多数并发场景下都是够用的。

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Created by xfyou 2018/6/8 14:01. */public class SnowFlakeIdGenerator {    // The initial time(2017-01-01)    private static final long INITIAL_TIME_STAMP = 1483200000000L;    // Machine ID bits    private static final long WORK_ID_BITS = 5L;    // DataCenter ID bits    private static final long DATACENTER_ID_BITS = 5L;    // The maximum machine ID supported is 31, which can quickly calculate the maximum decimal number that a few binary numbers can represent.    private static final long MAX_WORKER_ID = ~(-1L << WORK_ID_BITS);    // The maximum datacenter ID supported is 31    private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS);    // Sequence ID bits    private static final long SEQUENCE_BITS = 12L;    // The machine ID offset,12    private static final long WORKERID_OFFSET = SEQUENCE_BITS;    // The datacent ID offset,12+5    private static final long DATACENTERID_OFFSET = WORK_ID_BITS + SEQUENCE_BITS;    // The timestape offset, 5+5+12    private static final long TIMESTAMP_OFFSET = DATACENTER_ID_BITS + WORK_ID_BITS + SEQUENCE_BITS;    // Sequence mask,4095    private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);    // Worker ID ,0~31    private long workerId;    // Datacenter ID,0~31    private long datacenterId;    // Sequence,0~4095    private long sequence = 0L;    // Last timestamp    private long lastTimestamp = -1L;    public SnowFlakeIdGenerator(long workerId, long datacenterId) {        if (workerId > MAX_WORKER_ID || workerId < 0)            throw new IllegalArgumentException(String.format("WorkerID can't be greater than %d or less than 0", MAX_WORKER_ID));        if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0)            throw new IllegalArgumentException(String.format("DataCenterID can't be greater than %d or less than 0", MAX_WORKER_ID));        this.workerId = workerId;        this.datacenterId = datacenterId;    }    public synchronized long nextId() {        long timeStamp = System.currentTimeMillis();        if (timeStamp < lastTimestamp)            throw new RuntimeException("The current time less than last time");        if (timeStamp == lastTimestamp) {            sequence = (sequence + 1) & SEQUENCE_MASK;            if (0 == sequence)                timeStamp = tillNextMillis(lastTimestamp);        } else {            sequence = 0L;        }        lastTimestamp = timeStamp;        return (timeStamp - INITIAL_TIME_STAMP) << TIMESTAMP_OFFSET | (datacenterId << DATACENTERID_OFFSET) | (workerId << WORKERID_OFFSET) | sequence;    }    private long tillNextMillis(long lastTimestamp) {        long timestamp = System.currentTimeMillis();        while (timestamp <= lastTimestamp)            timestamp = System.currentTimeMillis();        return timestamp;    }    public static void main(String[] args) {        SnowFlakeIdGenerator generator = new SnowFlakeIdGenerator(1, 1);        ExecutorService executorService = Executors.newCachedThreadPool();        for (int i = 0; i < 5; i++) {            executorService.execute(new Runnable() {                @Override                public void run() {                    long id = generator.nextId();                    System.out.println(id);                }            });        }        executorService.shutdown();    }}

 一个可能的输出为:

189783462515970048189783462515970049189783462515970050189783462515970051189783462520164352

 

转载地址:http://gdaux.baihongyu.com/

你可能感兴趣的文章
标准与扩展ACL 、 命名ACL 、 总结和答疑
查看>>
使用@media实现IE hack的方法
查看>>
oracle体系结构
查看>>
Microsoft Exchange Server 2010与Office 365混合部署升级到Exchange Server 2016混合部署汇总...
查看>>
Proxy服务器配置_Squid
查看>>
【SDN】Openflow协议中对LLDP算法的理解--如何判断非OF区域的存在
查看>>
纯DIV+CSS简单实现Tab选项卡左右切换效果
查看>>
Centos7同时运行多个Tomcat
查看>>
使用CocoaPods过程中的几个问题
查看>>
Spring boot 整合CXF webservice 全部被拦截的问题
查看>>
Pinpoint跨节点统计失败
查看>>
机房带宽暴涨问题分析及解决方法
查看>>
XP 安装ORACLE
查看>>
八、 vSphere 6.7 U1(八):分布式交换机配置(vMotion迁移网段)
查看>>
[转载] 中华典故故事(孙刚)——19 万岁
查看>>
php5编译安装常见错误和解决办法集锦
查看>>
Unable to determine local host from URL REPOSITORY_URL=http://
查看>>
ORACLE配置,修改tnsnames.ora文件实例
查看>>
Workstation服务无法启动导致无法访问文件服务器
查看>>
Linux常用命令(一)
查看>>