基于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编译: 之前的几个文件没有中文的内容,都没 ...
随机推荐
- js判断鼠标是否停止移动
本程序实现当鼠标在一个特定的div内悬停n秒时,判断出已经停止移动. 思路: 1.定义全局变量鼠标移动状态imouse,定时器timer.当鼠标在div内移动时,imouse值为1,相反静止时值为0: ...
- RMAN还原32位数据库到64位实例的错误处理
将ORACLE 10g 32bit数据库还原到测试机ORACLE 10g 64bit的数据库实例上, 还原.恢复数据库后,使用open resetlogs打开数据库后,发现警告日志里面有ORA-120 ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
- 问题解决——MFC Ribbon 响应函数 错乱 执行其他函数
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...
- jq attr()改变checkbox的checked无效!!!!
今天做项目发现用attr()改变checked,实现全选功能的时候发现,第一次点击有效,之后点击全选功能便实效. 一开始以为是自己写错了,在各种碰壁之后,才猛然发现,原来这是jq的一个小bug. 在j ...
- ERROR! MySQL is running but PID file could not be found
/etc/init.d/mysql status提示ERROR! MySQL is running but PID file could not be found先打印MYSQL进程ps aux | ...
- cookie实现记住密码
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- JavaScript 基础回顾——数组
JavaScript是无类型语言,数组元素可以具有任意的数据类型,同一个数组的不同元素可以具有不同类型.数组的元素设置可以包含其他数组,便于模拟创建多维数组. 1.创建数组 在JavaScript中, ...
- [excel玩转表格教程][1G][AVI]
[excel玩转表格教程][1G][AVI] 下载地址 :http://www.fu83.cn/thread-222-1-1.html
- js/jquery/html前端开发常用到代码片段
1.IE条件注释 条件注释简介 IE中的条件注释(Conditional comments)对IE的版本和IE非IE有优秀的区分能力,是WEB设计中常用的hack方法.条件注释只能用于IE5以上,IE ...