- 浏览: 47206 次
- 性别:
- 来自: 深圳
文章分类
最新评论
import java.util.concurrent.atomic.AtomicInteger;
/**
* 这里的位是从高位说起的,第一位说的是符号位。
* 1bit + 41bit + 17bit + 5bit
* 第1bit固定是0 符号位不动 。
* 第2bit到第42bit使用时间蹉,精确到毫秒 41bit。 使用年限是69年
* 第43bit到第59bit使用自增的序列号 17bit 可用序列号最大131071个,说明一毫秒我们可以生成131071个不同的序列号。
* 第60bit到第64bit使用机器码 5bit 可以使系统可以分布式,最大分布式数量是32台机子。
* @author pdy
*/
public class IDGennerator {
//最大17bit的序列号是131071
private final static int max_orderNo = 131071;
//用于生成序列号
private AtomicInteger orderNo;
//机器码 (0-31)
private final static long machineCode = 31l;
//时间戳的掩码
private final static long time_code = Long.MAX_VALUE >>> 22;
public IDGennerator() {
orderNo = new AtomicInteger(0);
}
public long genneratorId(){
/**
* 时间戳
* 1、先去掉高23bit,保留当前时间的低41bit
* 2、将0到41bit移到高位去
*/
long currentTimeMillis = (System.currentTimeMillis() & time_code) << 22;
/**
* 序列号自增1和获取
*/
int orderNo = this.orderNo.incrementAndGet();
if(orderNo > max_orderNo){
//如果超过了最大序列号 则重置为0
if(!this.orderNo.compareAndSet(orderNo, 0)){
//这里使用cas操作,所以不需要加锁 1、操作失败了 则表示别的线程已经更改了数据,则直接进行自增并获取则可以了
orderNo = this.orderNo.incrementAndGet();
} else {
//操作成功后,则序列号为0了
orderNo = 0;
}
}
//符号位(1)bit、时间戳(2~42)bit | 序列号(43~59)bit | 机器码(60~64)bit
currentTimeMillis = currentTimeMillis | (orderNo << 14 >>> 9) | machineCode;
return currentTimeMillis;
}
//升级的版本
package com.hengyunsoft.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 1bit + 41bit + 17bit + 5bit
* | | | |
* | | | |
* 符合位 时间戳(毫秒) 序列号 机器码
* 第1bit固定是0 符号位不动 。
* 第2bit到第42bit使用时间蹉,精确到毫秒 41bit。 使用年限是69年
* 第43bit到第59bit使用自增的序列号 17bit 可用序列号最大131071个,说明一毫秒我们可以生成131071个不同的序列号。
* 第60bit到第64bit使用机器码 5bit 可以使系统可以分布式,最大分布式数量是32台机子。
* @author pdy
*/
public class SnowflakeIDGenerate implements IIDGenerate<Long>{
//最大17bit的序列号是131071
private final static int max_orderNo = 131071;
//用于生成序列号
private AtomicInteger orderNo;
//机器码 (0-31)
private final long machineCode;
//时间戳的掩码
private final static long time_code = Long.MAX_VALUE >>> 22;
/**
* 2015-01-01 00:00:00
* 1420041600210
* 因为我们的生成器可以使用69年,而我们想在这些时间里面,生成出来的id是逐渐自增的。
* 所以我这里指定了从什么时候开始使用id生成器。
*/
private final long startTime = 1420041600210L;
public SnowflakeIDGenerate(final long machineCode) {
if( 0 > machineCode || machineCode > 31){
throw new IllegalArgumentException("请注意,1、机器码在多台机器或应用间是不允许重复的!2、机器码取值仅仅在0~31之间");
}
this.machineCode = machineCode;
orderNo = new AtomicInteger(0);
}
public Long generate(){
/**
* 时间戳
* 1、先去掉高23bit,保留当前时间的低41bit
* 2、将0到41bit移到高位去
*/
long currentTimeMillis = time_code & (System.currentTimeMillis() - startTime) << 22;
/**
* 序列号自增1和获取
*/
int orderNo = this.orderNo.incrementAndGet();
if(orderNo > max_orderNo){
//如果超过了最大序列号 则重置为0
if(!this.orderNo.compareAndSet(orderNo, 0)){
//这里使用cas操作,所以不需要加锁 1、操作失败了 则表示别的线程已经更改了数据,则直接进行自增并获取则可以了
orderNo = this.orderNo.incrementAndGet();
} else {
//操作成功后,则序列号为0了
orderNo = 0;
}
}
//符号位(1)bit、时间戳(2~42)bit | 序列号(43~59)bit | 机器码(60~64)bit
return currentTimeMillis | (orderNo << 14 >>> 9) | machineCode;
}
}
/**
* 这里的位是从高位说起的,第一位说的是符号位。
* 1bit + 41bit + 17bit + 5bit
* 第1bit固定是0 符号位不动 。
* 第2bit到第42bit使用时间蹉,精确到毫秒 41bit。 使用年限是69年
* 第43bit到第59bit使用自增的序列号 17bit 可用序列号最大131071个,说明一毫秒我们可以生成131071个不同的序列号。
* 第60bit到第64bit使用机器码 5bit 可以使系统可以分布式,最大分布式数量是32台机子。
* @author pdy
*/
public class IDGennerator {
//最大17bit的序列号是131071
private final static int max_orderNo = 131071;
//用于生成序列号
private AtomicInteger orderNo;
//机器码 (0-31)
private final static long machineCode = 31l;
//时间戳的掩码
private final static long time_code = Long.MAX_VALUE >>> 22;
public IDGennerator() {
orderNo = new AtomicInteger(0);
}
public long genneratorId(){
/**
* 时间戳
* 1、先去掉高23bit,保留当前时间的低41bit
* 2、将0到41bit移到高位去
*/
long currentTimeMillis = (System.currentTimeMillis() & time_code) << 22;
/**
* 序列号自增1和获取
*/
int orderNo = this.orderNo.incrementAndGet();
if(orderNo > max_orderNo){
//如果超过了最大序列号 则重置为0
if(!this.orderNo.compareAndSet(orderNo, 0)){
//这里使用cas操作,所以不需要加锁 1、操作失败了 则表示别的线程已经更改了数据,则直接进行自增并获取则可以了
orderNo = this.orderNo.incrementAndGet();
} else {
//操作成功后,则序列号为0了
orderNo = 0;
}
}
//符号位(1)bit、时间戳(2~42)bit | 序列号(43~59)bit | 机器码(60~64)bit
currentTimeMillis = currentTimeMillis | (orderNo << 14 >>> 9) | machineCode;
return currentTimeMillis;
}
//升级的版本
package com.hengyunsoft.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 1bit + 41bit + 17bit + 5bit
* | | | |
* | | | |
* 符合位 时间戳(毫秒) 序列号 机器码
* 第1bit固定是0 符号位不动 。
* 第2bit到第42bit使用时间蹉,精确到毫秒 41bit。 使用年限是69年
* 第43bit到第59bit使用自增的序列号 17bit 可用序列号最大131071个,说明一毫秒我们可以生成131071个不同的序列号。
* 第60bit到第64bit使用机器码 5bit 可以使系统可以分布式,最大分布式数量是32台机子。
* @author pdy
*/
public class SnowflakeIDGenerate implements IIDGenerate<Long>{
//最大17bit的序列号是131071
private final static int max_orderNo = 131071;
//用于生成序列号
private AtomicInteger orderNo;
//机器码 (0-31)
private final long machineCode;
//时间戳的掩码
private final static long time_code = Long.MAX_VALUE >>> 22;
/**
* 2015-01-01 00:00:00
* 1420041600210
* 因为我们的生成器可以使用69年,而我们想在这些时间里面,生成出来的id是逐渐自增的。
* 所以我这里指定了从什么时候开始使用id生成器。
*/
private final long startTime = 1420041600210L;
public SnowflakeIDGenerate(final long machineCode) {
if( 0 > machineCode || machineCode > 31){
throw new IllegalArgumentException("请注意,1、机器码在多台机器或应用间是不允许重复的!2、机器码取值仅仅在0~31之间");
}
this.machineCode = machineCode;
orderNo = new AtomicInteger(0);
}
public Long generate(){
/**
* 时间戳
* 1、先去掉高23bit,保留当前时间的低41bit
* 2、将0到41bit移到高位去
*/
long currentTimeMillis = time_code & (System.currentTimeMillis() - startTime) << 22;
/**
* 序列号自增1和获取
*/
int orderNo = this.orderNo.incrementAndGet();
if(orderNo > max_orderNo){
//如果超过了最大序列号 则重置为0
if(!this.orderNo.compareAndSet(orderNo, 0)){
//这里使用cas操作,所以不需要加锁 1、操作失败了 则表示别的线程已经更改了数据,则直接进行自增并获取则可以了
orderNo = this.orderNo.incrementAndGet();
} else {
//操作成功后,则序列号为0了
orderNo = 0;
}
}
//符号位(1)bit、时间戳(2~42)bit | 序列号(43~59)bit | 机器码(60~64)bit
return currentTimeMillis | (orderNo << 14 >>> 9) | machineCode;
}
}
发表评论
-
api调用计数限制
2017-10-10 09:56 511import java.util.concurrent.Con ... -
多个key,单个value的缓存实现
2017-09-11 17:58 588假如一条记录可以用id,idcard,name分别唯一的查询到 ... -
java模拟多处理器调度
2017-08-14 10:10 471import java.util.LinkedList; im ... -
java读写锁升级与降级、并会发现死锁。抛出异常
2017-08-10 16:35 971package com.huawei.test; impor ... -
用java代码来定时增量同步数据库表的实现代码
2017-04-20 17:08 11781import java.io.Serializable; im ... -
spring声明式事物不起作用的原因
2017-03-04 21:52 53509:41:37,848 [main] INFO jdbc. ... -
javac 和 java不同小版本时会报错,最后配置一样
2017-02-24 14:20 2859Information:Using javac 1.8.0_1 ... -
Rabbitmq高可用设计思路
2016-10-14 17:41 2912Rabbitmq高可用设计思路 ... -
rabbitmq实现高吞吐量的rpc调用
2016-10-09 16:21 9304rabbitmq实现rpc调用基本思路: 客户端(client ... -
shiro Ajax请求未登陆响应json串实现
2016-09-18 11:00 3881package com.cc.sec; import jav ... -
md5加密,jdk7 与jdk8对含有中文的明文加密注意
2015-12-29 12:27 1703private static final String ALG ... -
通过修改web.xml让服务器重启的问题
2015-11-26 09:28 922通过修改web.xml让服务器重启的问题? 通过修改web.x ... -
使用java反射机制实现java的深拷贝
2014-09-10 11:32 1387import java.lang.reflect.Constr ...
相关推荐
《深入理解百度开源的分布式ID生成器UidGenerator》 在分布式系统中,生成全局唯一ID是一个常见的需求,而百度开源的UidGenerator就是这样一款强大的工具。它基于Snowflake模型,为系统提供了高性能且具有唯一性的...
结合上述信息,"idGenerate"这个文件很可能是包含了一个Java实现的分布式代码生成器项目,可能包含了Snowflake算法或者其他分布式ID生成策略的源代码。通过学习和理解这些代码,我们可以更好地掌握在Java环境中如何...
在Java中实现Snowflake算法,一般会创建一个ID生成器类,包含以下关键步骤: 1. **初始化**: 设置起始时间戳和工作节点ID,这些值通常在系统启动时配置。 2. **ID生成**: 获取当前毫秒数,与起始时间戳相减得到...
分布式ID生成器是现代互联网系统中的重要组成部分,它在大数据量和高并发的场景下扮演着关键角色。本文将深入探讨“通用、灵活、高性能”的分布式ID生成器的设计原理、实现方式以及它在服务器应用和分布式服务/框架...
Vesta,uidgennator等分布式id生成方案 UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境...
分布式ID生成器 VESTA 是一个专为解决大型分布式系统中唯一标识符生成问题而设计的工具。在现代互联网应用中,随着业务的扩展和数据量的增长,单一服务器已无法满足高并发、高性能的需求,因此分布式系统应运而生。...
该项目是一款基于C语言开发的分布式ID生成器,名为idCreator。该系统由120个文件组成,包括52个头文件、50个C语言源文件、1个Git忽略文件、1个LICENSE文件、1个Markdown描述文件以及客户端相关的配置和脚本文件。该...
分布式ID生成器是解决大规模系统中唯一标识符生成问题的关键技术。在数据库水平拆分的背景下,为了确保每个数据记录的唯一性,ID生成器变得尤为重要。本文将深入探讨一种名为SnowflakeX的分布式ID生成解决方案,它是...
分布式ID生成器是大型互联网系统中不可或缺的一部分,其主要任务是为系统中的各种实体生成全局唯一的标识符(ID)。在复杂分布式环境下,选择合适的ID生成策略对于系统的性能、可用性和可扩展性至关重要。以下是几种...
本项目是一款基于Java语言的分布式ID生成器设计源码,包含30个文件,其中26个为Java源文件,还包括Git忽略文件、许可证文件、Markdown文档和XML配置文件。该系统能够生成带有校验码的19位Long ID、不超过22位的短...
分布式ID生成器 VESTA-jar+源码 Vesta是一款通用的ID产生器,互联网俗称统一发号器,它具有全局唯一、粗略有序、可反解和可制造等特性,它支持三种发布模式:嵌入发布模式、中心服务器发布模式、REST发布模式,根据...
分布式id生成器--可以直接拿来找对应的码源
本id生成器基于数据库和redis两种方式,redis性能更高;目前很多项目正在使用中,支持分布式、高并发、高性能,拿来即可使用。
系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID的方法有很多,适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略。
全局唯一ID作为一种唯一标识来区分数据,可用作订单号、用户ID等。ID生成器是生成全局唯一ID的工具,可封装为一种基础服务为其他业务提供服务。因此此项目就是用springboot封装ID生成器,让各种业务系统调用
- ID生成器模块:负责与MySQL交互,获取新的ID。 - 请求处理器模块:接收来自客户端的请求,使用goroutine进行异步处理。 - 锁管理模块:实现分布式锁,防止ID分配冲突。 - 客户端接口:提供给其他系统调用的API接口...
迄今为止最全面的分布式主键ID生成器。优化的雪花算法(SnowFlake)——雪花漂移算法,在缩短ID长度的同时,具备极高瞬时并发处理能力(50W/0.1s)。 原生支持 C#/Java/Go/Rust/C/SQL 等多语言,且提供 PHP 扩展及 ...
迄今为止最全面的分布式主键ID生成器。 优化的雪花算法(SnowFlake)——雪花漂移算法,在缩短ID长度的同时,具备极高瞬时并发处理能力(50W/0.1s)。 原生支持 C#/Java/Go/Rust/C/SQL 等多语言,且提供 PHP 扩展及 ...
因此,引入专门的分布式ID生成器解决方案成为必要。 ### UUID方案 UUID(Universally Unique Identifier)是一种常见的生成全局唯一ID的方法,但它存在一些问题: 1. **存储不便**:UUID由16字节的128位组成,通常...