基于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编译: 之前的几个文件没有中文的内容,都没 ...
随机推荐
- Eclipse部署项目的原理简介eclipse,wtpwebapps,tomcat
转载请注明出处! http://www.cnblogs.com/libingbin/ 感谢您的阅读.如果文章对您有用,那么请轻轻点个赞,以资鼓励.
- JavaScript Array和string的转换
Array类可以如下定义: var aValues = new Array(); 如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20); -------- ...
- ORACLE数据库SQL语句的执行过程
SQL语句在数据库中处理过程是怎样的呢?执行顺序呢?在回答这个问题前,我们先来回顾一下:在ORACLE数据库系统架构下,SQL语句由用户进程产生,然后传到相对应的服务端进程,之后由服务器进程执行该SQ ...
- JVM之PC寄存器(Program Counter Register)
基本特性: 当前线程执行的字节码的行号指示器. Java虚拟机支持多个线程同时执行,每一个线程都有自己的pc寄存器. 任意时刻,一个线程都只会执行一个方法的代码,称为该线程的当前方法,对于非nativ ...
- Centos网络配置
网上搜索:centos网络配置的方法,主要包括dns.网关.IP地址,主要是配置resolv.conf\network\ifcfg-eth0这些网络配置文件. 稍后我会就centos7的网络配置进行实 ...
- 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 | ...
- android Dialog实例
Dialog类 public class DialogUtil { public static Dialog EditDialog(Activity context,View view){ final ...
- 【Windows编程】系列第五篇:GDI图形绘制
上两篇我们学习了文本字符输出以及Unicode编写程序,知道如何用常见Win32输出文本字符串,这一篇我们来学习Windows编程中另一个非常重要的部分GDI图形绘图.Windows的GDI函数包含数 ...
- 从人类社会的角度看OO(独家视角)
引言 在OO的工作中,我们一定会涉及到类,抽象类和接口.那么类和抽象类以及接口到底扮演的什么角色? 本文主要是从人类社会的角度阐述类与抽象类以及接口的"社会"关系,从而让我们抛弃书 ...
- Java Generics and Collections-2.1
2.1 子类化以及替换原理 为什么List<Integer> 不是List<Number> 的子类? 首先看下面的代码,这段代码是编译不过的 package java_gene ...