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();
}
}

一个可能的输出为:

189783462515970048
189783462515970049
189783462515970050
189783462515970051
189783462520164352

Java 实现的SnowFlake生成UUID (Java代码实战-007)的更多相关文章

  1. [转]java二维码生成与解析代码实现

    转载地址:点击打开链接 二维码,是一种采用黑白相间的平面几何图形通过相应的编码算法来记录文字.图片.网址等信息的条码图片.如下图 二维码的特点: 1.  高密度编码,信息容量大 可容纳多达1850个大 ...

  2. java二维码生成与解析代码实现

    TwoDimensionCode类:二维码操作核心类 package qrcode; import java.awt.Color; import java.awt.Graphics2D; import ...

  3. Java编程思想-注解生成外部例子代码

    如果本文帮助到您,请点击下面的链接,这是本人的网站,以示鼓励,谢谢!链接绝对安全! 本人的网站 java注解属于java中高大上的功能,许多开源框架都使用了java注解的功能.比如spring,hib ...

  4. 生成UUID的代码

    代码: String reqId = UUID.randomUUID().toString().replace("-", "");

  5. java生成UUID

    UUID介绍: UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.按照开放软件基金会(OSF) ...

  6. JAVA基础知识(一)—JAVA概述

    JAVA概述 1991 年Sun公司的James Gosling(詹姆斯·高斯林)等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒.PDA等的微处理器: 1994年将Oak语言更名 ...

  7. 利用Java生成UUID

    UUID是什么? UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分.其目的,是 ...

  8. java 生成UUID

    UUID(Universally Unique Identifier)全局唯一标识符,是一个128位长的数字,一般用16进制表示. 算法的核心思想是结合机器的网卡.当地时间.一个随即数来生成UUID, ...

  9. java生成UUID通用唯一识别码 (Universally Unique Identifier)

    转自:http://blog.csdn.net/carefree31441/article/details/3998553 UUID含义是通用唯一识别码 (Universally Unique Ide ...

随机推荐

  1. POI Excel表格合并,边框设置

    RegionUtil.setBorderLeft(1, cellRangeAddress, sheet, wb); RegionUtil.setBorderBottom(1, cellRangeAdd ...

  2. perf使用示例2

    perf使用示例2 性能调优工具如 perf,Oprofile 等的基本原理都是对被监测对象进行采样,最简单的情形是根据 tick 中断进行采样,即在 tick 中断内触发采样点,在采样点里判断程序当 ...

  3. Understanding Linux CPU stats

    Your Linux server is running slow, so you follow standard procedure and run top. You see the CPU met ...

  4. 混沌分形之逻辑斯蒂(Logistic)映射系统

    前几天,有个同事看到我生成的一幅逻辑斯蒂分岔图像后,问我:“这是咪咪吗?”我回答:“淫者见淫.”好吧,这里将生成几种分岔映射图形,包括逻辑斯蒂映射系统,正弦映射系统和曼德勃罗映射系统.实际上这几种图形 ...

  5. windows包管理器chocolatey

    1.安装chocolatey打开cmd.exe执行@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Obj ...

  6. FastReport.Net 入门

    任何一门编程技术入门体验都是以“Hello World”开始的,但我想再复杂一点的“Hello World”,才能算真正的入门.   FastReport.Net V1.2.76 ,vs2008 在 ...

  7. [leetcode]ZigZag Conversion @ Python

    原题地址:https://oj.leetcode.com/problems/zigzag-conversion/ 题意: The string "PAYPALISHIRING" i ...

  8. Linq to Sql并发冲突及处理策略

    0. 并发冲突的示例 单用户的系统现在应该比较罕见了,一般系统都会有很多用户在同时进行操作:在多用户系统中,涉及到的一个普遍问题:当多个用户“同时”更新(修改或者删除)同一条记录时,该如何更新呢?   ...

  9. 遮罩层中的相对定位与绝对定位(Ajax)

    前提:公司最近做的一个项目列表,然后点击项目,出现背景遮罩层,弹出的数据框需要异步加载数据数据,让这个数据框居中,搞了两天终于总算达到Boss满意的程度,做了半年C/S,反过来做B/S,顿时感到技术还 ...

  10. Android -- Dialog动画

    window_in.xml <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ...