基于Twitter-Snowflake的java改进版,去状态化实现
package jeffery; import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.UUID; /**
* Created by jeffery on 2016/5/20.
* tweeter的snowflake 移植到Java.参考资料:https://github.com/twitter/snowflake
* id构成: 42位的时间前缀 + 10位的节点标识 + 12位的sequence避免并发的数字(12位不够用时强制得到新的时间前缀)
* id单调递增,长整型
* 注意这里进行了小改动: snowkflake是5位的datacenter加5位的机器id; 这里变成使用10位的机器id
* snowkflake当时间调整时将拒绝分配ID,这里改成分配UUID的tMostSignificantBits
* 通过取服务器名中的编号来分配机器id,实现了去状态化
* 使用:long id = IdWorker.nextId();
*/
public final class IdWorker {
private static final long workerId;//每台机器分配不同的id
private static final long epoch = 1472693086614L; // 时间起始标记点,作为基准,一般取系统的最近时间
private static final long workerIdBits = 10L; // 机器标识位数
private static final long maxWorkerId = -1L ^ -1L << workerIdBits;// 机器ID最大值: 1023
private static long sequence = 0L; // 0,并发控制
private static final long sequenceBits = 12L; //毫秒内自增位 private static final long workerIdShift = sequenceBits; // 12
private static final long timestampLeftShift = sequenceBits + workerIdBits;// 22
private static final long sequenceMask = -1L ^ -1L << sequenceBits; // 4095,111111111111,12位
private static long lastTimestamp = -1L; static {
String hostName = null;
try {
InetAddress netAddress = InetAddress.getLocalHost();
hostName = netAddress.getHostName();
} catch (UnknownHostException e) {
}
if (null != hostName && !"".equals(hostName)) {
String hostNo = "";
for (int i = 0; i < hostName.length(); i++) {
if (hostName.charAt(i) >= 48 && hostName.charAt(i) <= 57) {
//取最后一组数字
if ("".equals(hostNo) || (hostName.charAt(i - 1) >= 48 && hostName.charAt(i - 1) <= 57))
hostNo += hostName.charAt(i);
else {
hostNo = "";
hostNo += hostName.charAt(i);
}
}
}
if (null != hostNo && !"".equals(hostNo)) {
workerId = Integer.parseInt(hostNo) % maxWorkerId;
} else {
workerId = 1;//TODO:当机器名不包含编号时,采用手动编号,需要在配置文件中指定 } } else {
workerId = 1;
}
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
} public static synchronized long nextId() {
long timestamp = timeGen();
if (lastTimestamp == timestamp) { // 如果上一个timestamp与新产生的相等,则sequence加一(0-4095循环); 对新的timestamp,sequence从0开始
sequence = sequence + 1 & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);// 重新生成timestamp
}
} else {
sequence = 0;
} if (timestamp < lastTimestamp) {
UUID uuid = UUID.randomUUID();
return uuid.getMostSignificantBits();
} lastTimestamp = timestamp;
return timestamp - epoch << timestampLeftShift | workerId << workerIdShift | sequence;
} /**
* 等待下一个毫秒的到来, 保证返回的毫秒数在参数lastTimestamp之后
*/
private static long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
} /**
* 获得系统当前毫秒数
*/
private static long timeGen() {
return System.currentTimeMillis();
} }
基于Twitter-Snowflake的java改进版,去状态化实现的更多相关文章
- Twitter Snowflake 的Java实现
在关闭显示的情况下, 可以达到每毫秒3万个的生成速度 /** * An Implementation of Twitter Snowflake ID Generator */ public class ...
- 交易所频频跑路?Baccarat去中心化交易平台助力资金安全
过去,黑客攻击可能是交易所跑路的最常见原因.自OKEx事件以来,这些交易所暂停提币或跑路还多了一个原因,就是因创始人正在协助调查. 据不完全统计,自OKEx于10月16日宣布暂停提币后不到两个月,已经 ...
- NGK公链:去中心化交易+挖矿生态体系共舞
NGK生态公链是一个安全.透明.专业的去中心化商业应用平台.作为一条具有技术信任甚至是公众信任的公链,NGK以区块链技术为支撑,利用区块链透明.公正.公开.数据不可篡改.分布式存储.可追溯等技术优势, ...
- 基于Twitter的Snowflake算法实现分布式高效有序ID生产黑科技(无懈可击)
参考美团文档:https://tech.meituan.com/2017/04/21/mt-leaf.html Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万 ...
- 基于AQS实现的Java并发工具类
本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 【SpringSecurity系列2】基于SpringSecurity实现前后端分离无状态Rest API的权限控制原理分析
源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...
- snowflake算法(java版)
转自:http://www.cnblogs.com/haoxinyue/p/5208136.html 1. 数据库自增长序列或字段 最常见的方式.利用数据库,全数据库唯一. 优点: 1)简单,代码方 ...
- 基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案
基于Windows下处理Java错误:编码GBK的不可映射字符的解决方案 最近在研究Java,涉及命令行编译,使用notepad++编辑器,然后使用javac编译: 之前的几个文件没有中文的内容,都没 ...
随机推荐
- 敏捷开发XP
一.组建XP团队 在XP团队中,由以下组成 二.项目相关环境 1.利益相关者:与PM一样,对项目进行管理 2.执行发起人:最终客户(必须定期演示) 三.XP组成 四.思考 1.结 ...
- ORA-02266: unique/primary keys in table referenced by enabled foreign keys
在数据库里面使用TRUNCATE命令截断一个表的数据时,遇到如下错误 SQL >TRUNCATE TABLE ESCMOWNER.SUBX_ITEM ORA-02266: unique/prim ...
- android Bundle savedInstanceState用途
经常会出现用户按到home键,退出了界面,或者安卓系统意外回收了应用的进程,这种情况下,使用Bundle savedInstanceState就可以用户再次打开应用的时候恢复的原来的状态 (以下转自: ...
- liunx作业一
一.linux发行版 linux发行版是以linux为内核,包含了系统软件和应用软件.简化系统安装的工具.软件安装升级的集成管理器. 典型的linux发行版包括:linux内核,一些GNU程序库和工具 ...
- UrlRewritingNet伪静态的使用方法与解决方案(URL重写)
在建站初期时,我们往往需要考虑的是使用真静态还是伪静态,这对于往后的站点配置,延展性都会产生深远的影响. 我使用伪静态的唯一目的:SEO优化.毋容置疑,伪静态在对于Spider是非常有利的,因此,我更 ...
- CML相关
!!:执行上一条命令 !blah:执行最近的以 blah 开头的命令,如 !ls !blah:p:仅打印输出,而不执行 !$:上一条命令的最后一个参数,与 Alt + . 相同 !$:p:打印输出 ! ...
- Git的使用的简单介绍
节选自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 git是一个分布式的引擎, ...
- Windbg跟踪临界区的BUG
最近跟踪了一个程序的界面卡死问题,该卡死偶尔出现,在抓到一次dump后用windbg载入分析,打印出函数调用堆栈后,一眼可以看出是临界区死锁了. 代码: 0:000:x86> kb ChildE ...
- Cinder 调试 - 无法挂载到虚拟机
1.问题 我们有时候在通过云主机挂载云硬盘的时候会出现挂载不上的问题.像这中问题有多种情况导致的. 看一下我遇到的两种情况. 1.权限问题 在cinder节点查看 /var/log/cinder/ci ...
- POJ2425 A Chess Game[博弈论 SG函数]
A Chess Game Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 3917 Accepted: 1596 Desc ...