import java.lang.management.ManagementFactory;
import java.math.BigInteger;
import java.util.concurrent.locks.ReentrantLock;
/**
* 产生唯一ID的snow flake
* 41(timestamp)+16(ip)+18(pid)+8(seq)
*
* @author changstone
*
*/
public class Snowflake {
/**
* 纪元开始,2018-01-01
*/
private static final long TH_EPOCH = 1514736000000L;
private int timestampBits = 41;
private int ipBits = 16;
private int processIdBits = 18;
private int sequenceBits = 8;
@SuppressWarnings("unused")
private long maxTimestamp = -1L ^ (-1L << timestampBits);
private long maxIp = -1L ^ (-1L << ipBits);
private long maxProcessId = -1L ^ (-1L << processIdBits);
private long sequenceMask = -1L ^ (-1L << sequenceBits);
private int processIdShift = sequenceBits;
private int ipSfhit = sequenceBits + processIdBits;
private int timestampShift = sequenceBits + processIdBits + ipBits;
private long ip = 1L;
private long processId = 1L;
private long sequence = 1L;
private long lastTimestamp = 1L;
private final ReentrantLock lock = new ReentrantLock();
public Snowflake(String ipAddr) {
String[] ipArray = ipAddr.split("\\.");
ip = Long.valueOf(ipArray[2]) << 8 | Long.valueOf(ipArray[3]) & maxIp;
processId = Long.valueOf(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]) & maxProcessId;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = 1L;
for (;;) {
timestamp = System.currentTimeMillis();
if (timestamp > lastTimestamp) {
return timestamp;
}
}
}
public String nextId() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
long timestamp = System.currentTimeMillis();
if (timestamp < TH_EPOCH) {
throw new RuntimeException("clock is moving backwards.Reject requests before epoch!");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
long idLow = ip << ipSfhit | processId << processIdShift | sequence;
BigInteger idHign = BigInteger.valueOf(timestamp - TH_EPOCH).shiftLeft(timestampShift);
BigInteger id = idHign.add(BigInteger.valueOf(idLow));
return id.toString(10);
} finally {
lock.unlock();
}
}
public String nextIdHex() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
long timestamp = System.currentTimeMillis();
if (timestamp < TH_EPOCH) {
throw new RuntimeException("clock is moving backwards.Reject requests before epoch!");
}
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
long idLow = ip << ipSfhit | processId << processIdShift | sequence;
BigInteger idHign = BigInteger.valueOf(timestamp - TH_EPOCH).shiftLeft(timestampShift);
BigInteger id = idHign.add(BigInteger.valueOf(idLow));
return id.toString(16);
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Snowflake snow = new Snowflake("188.89.56.123");
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextId());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
System.out.println(snow.nextIdHex());
}
}
雪花算法(ip+进程pid)
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 这次对之前的代理池1.0版本进行了升级,可用性大大增加了,也增加了一些IP源头的获取,包括西刺高匿代理前50页的I...