基于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编译: 之前的几个文件没有中文的内容,都没 ...
随机推荐
- 史上最全的ASP.NET MVC路由配置
MVC将一个Web应用分解为:Model.View和Controller.ASP.NET MVC框架提供了一个可以代替ASP.NETWebForm的基于MVC设计模式的应用. AD:51CTO 网+ ...
- Coding道场:第一次
10/23日,我在部门内部进行了一次内部学习,使用目前流行的Coding Dojo(道场)方式,进行了TDD开发的演练.演练的题目如下: 有关Coding道场的介绍,请自行百度一下,我就不再多 ...
- C#.NET万能数据库访问封装类(ACCESS、SQLServer、Oracle)
using System; using System.Collections; using System.Collections.Specialized; using System.Data; usi ...
- ORA-19502: write error on file "xxxxx", block number xxxx
错误现象: 在ORACLE 10g下为表空间IGNITE_EGVSQL01增加数据文件时,报如下错误: SQL> ALTER TABLESPACE IGNITE_EGVSQL01 AD ...
- mysql权限与安全
一.MySQL权限系统通过两个阶段进行认证: (A) 对用户进行身份认证,IP地址和用户名联合, (B) 对合法用户赋予相应权限,权限表在数据库启动的时候载入内存中. 二.在权限的存取过程中,会用到& ...
- Java怎么添加背景图片
首先,导入相关的包: import java.awt.BorderLayout; import java.awt.Container; import javax.swing.ImageIcon; im ...
- linux fdisk命令使用
fdisk 对硬盘及分区的操作,进入fdisk 对硬盘操作阶段 我们可以对硬盘进行分区操作,前提是您把fdisk -l 弄明白了:通过fdisk -l ,我们能找出机器中所有硬盘个数及设备名称:比如上 ...
- Si2151/41 6th Generation Silicon TV Tuner ICs
The Si2151/41 are the industry's most advanced silicon TV tuner ICs supporting all worldwide terre ...
- Sublime Text 技巧
让sublime text2支持中文 安装Sublime Package Control 在Sublime Text 2上用Ctrl+-打开控制台并在里面输入以下代码,Sublime Text 2就会 ...
- [django]表格的添加与删除实例(可以借鉴参考)
自己并未采用任何表格插件,参考网上例子,自己编写出来的django网页实例,请各位参考! 首先看图做事,表格布局采用bootstrap,俗话说bootstrap橹多了就会css了,呵呵,下面看图: 上 ...