永不重复的id生成器

(1)需要导入的包
主要用在格式化日FastDateFormat.getInstance("yyyyMMddHHmmssSSS");
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
(2)IdGenerator类
import org.apache.commons.lang3.time.FastDateFormat;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 与snowflake算法区别,返回字符串id,占用更多字节,但直观从id中看出生成时间
* 改写了生成时间的format方法
* @Project concurrency
*/
public enum IdGenerator {
INSTANCE;
private long workerId; //用ip地址最后几个字节标示
private long datacenterId = 0L; //可配置在properties中,启动时加载,此处默认先写成0
private long sequence = 0L;
private long workerIdBits = 8L; //节点ID长度
private long datacenterIdBits = 2L; //数据中心ID长度,可根据时间情况设定位数
private long sequenceBits = 12L; //序列号12位
private long workerIdShift = sequenceBits; //机器节点左移12位
private long datacenterIdShift = sequenceBits + workerIdBits; //数据中心节点左移14位
private long sequenceMask = -1L ^ (-1L << sequenceBits); //4095
private long lastTimestamp = -1L;
private static final FastDateFormat FAST_DATE_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmssSSS");
IdGenerator(){
workerId = 0x000000FF & getLastIP();
}
public synchronized String nextId() {
long timestamp = timeGen(); //获取当前毫秒数
//如果服务器时间有问题(时钟后退) 报错。
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只有12bit,所以和sequenceMask相与一下,去掉高位
sequence = (sequence + 1) & sequenceMask;
//判断是否溢出,也就是每毫秒内超过4095,当为4096时,与sequenceMask相与,sequence就等于0
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp); //自旋等待到下一毫秒
}
} else {
sequence = 0L; //如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加
}
lastTimestamp = timestamp;
long suffix = (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;
//String datePrefix = DateFormatUtils.format(timestamp, "yyyyMMddHHmmssSSS");
String datePrefix = FAST_DATE_FORMAT.format(timestamp);
return datePrefix + suffix;
}
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
protected long timeGen() {
return System.currentTimeMillis();
}
private byte getLastIP(){
byte lastip = 0;
try{
InetAddress ip = InetAddress.getLocalHost();
byte[] ipByte = ip.getAddress();
lastip = ipByte[ipByte.length - 1];
} catch (UnknownHostException e) {
e.printStackTrace();
}
return lastip;
}
}
(3)使用举例
String id = IdGenerator.INSTANCE.nextId()
永不重复的id生成器的更多相关文章
- IDUtil 永不重复的ID
package com.xxx.common.util; import java.util.Random; /** * 各种id生成策略 * * @version 1.0 */ public clas ...
- IOS ID生成器
// // IdGenerator.m // Copyright (c) 2014年 青岛拓宇网络科技有限公司. All rights reserved. // #import "IdGen ...
- js生成一个不重复的ID的函数的进化之路
在MongoDB中的ObjectID,可以理解为是一个不会重复的ID,这里有个链接http://blog.csdn.net/xiamizy/article/details/41521025感兴趣可以去 ...
- 分布式ID生成器 zz
简介 这个是根据twitter的snowflake来写的.这里有中文的介绍. 如上图所示,一个64位ID,除了最左边的符号位不用(固定为0,以保证生成的ID都是正数),还剩余63位可用. 下面的代码与 ...
- 游戏服务器ID生成器组件
游戏服务器程序中,经常需要生成全局的唯一ID号,这个功能很常用,本文将介绍一种通用ID生成组件.游戏服务器程序中使用此组件的场景有: 创建角色时,为其分配唯一ID 创建物品时,每个物品需要唯一ID 创 ...
- ID生成器详解
概述 ID 生成器也叫发号器,它的主要目的就是"为一个分布式系统的数据object产生一个唯一的标识",但其实在一个真实的系统里可能也可以承担更多的作用.概括起来主要有以下几点: ...
- twitter的ID生成器的snowFlake算法的自造版
snowFlake算法在生成ID时特别高效,可参考:https://segmentfault.com/a/1190000011282426 SnowFlake算法生成id的结果是一个64bit大小的整 ...
- c#分布式ID生成器
c#分布式ID生成器 简介 这个是根据twitter的snowflake来写的.这里有中文的介绍. 如上图所示,一个64位ID,除了最左边的符号位不用(固定为0,以保证生成的ID都是正数),还剩余 ...
- ID 生成器 雪花算法
https://blog.csdn.net/wangming520liwei/article/details/80843248 ID 生成器 雪花算法 2018年06月28日 14:58:43 wan ...
随机推荐
- unittest生产html测试报告
需要添加HTMLTestRunner.py文件,我用的ubuntu16.04下的python3.5.2,所以我放在/usr/lib/python3.5下 import unittest import ...
- 百度AI
官网:http://ai.baidu.com/tech/face SDK:https://ai.baidu.com/sdk#bfr API说明 百度Face SDK Android 版是一种面向 An ...
- H5音乐自动播放ios//禁止安卓手机图片点击
定义音乐按钮 <div id="music-btn" class="o-play" style="width: 24px; height: 24 ...
- Spring Cloud,Dubbo及HSF对比
Round 1:背景 Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿里巴巴集团的各成员站点.阿里巴巴近几年对开源社区的贡献不论在国内还是国外都是引人注目的,比如:JStorm捐赠给Apa ...
- JMS(Java消息服务)与消息队列ActiveMQ基本使用(一)
最近的项目中用到了mq,之前自己一直在码农一样的照葫芦画瓢.最近几天研究了下,把自己所有看下来的文档和了解总结一下. 一. 认识JMS 1.概述 对于JMS,百度百科,是这样介绍的:JMS即Java消 ...
- 为wordpress博客网站替换鼠标样式
第一种方法是使用插件来实现这个功能,Unique Cursor 插件.可以在后台直接安装启用,然后就可以设置喜欢鼠标样式,点击保存就可以了.切记在选择的同时有二个选项一个是disable意思是关闭还 ...
- PHP全栈从入门到精通1
thinkphp框架,是一堆代码(常量,方法,和类)的集合,框架是一个半成品的应用,还包含一些优秀的设计模式. 框架的使用,代码风格不一样,维护难,项目生命周期短,功能扩展存在局限,好处为,简单,快捷 ...
- [Swift]LeetCode234. 回文链表 | Palindrome Linked List
Given a singly linked list, determine if it is a palindrome. Example 1: Input: 1->2 Output: false ...
- [Swift]LeetCode566. 重塑矩阵 | Reshape the Matrix
In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new o ...
- [Swift]LeetCode845. 数组中的最长山脉 | Longest Mountain in Array
Let's call any (contiguous) subarray B (of A) a mountain if the following properties hold: B.length ...