|
@@ -1,7 +1,7 @@
|
|
|
package com.fdkk.sxz.util;
|
|
|
|
|
|
import com.github.pagehelper.util.StringUtil;
|
|
|
-import lombok.extern.log4j.Log4j2;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
import java.lang.management.ManagementFactory;
|
|
|
import java.net.InetAddress;
|
|
@@ -15,7 +15,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|
|
* 3 * @Date: 2020/12/9 16:07
|
|
|
* 4
|
|
|
*/
|
|
|
-@Log4j2
|
|
|
+@Slf4j
|
|
|
public class SnowFlakeUUidUtils {
|
|
|
|
|
|
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
|
|
@@ -26,19 +26,19 @@ public class SnowFlakeUUidUtils {
|
|
|
// 数据中心标识位数
|
|
|
private final static long datacenterIdBits = 5L;
|
|
|
// 机器ID最大值
|
|
|
- private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
|
|
+ private final static long maxWorkerId = -1L ^ (-1L << SnowFlakeUUidUtils.workerIdBits);
|
|
|
// 数据中心ID最大值
|
|
|
- private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
|
|
|
+ private final static long maxDatacenterId = -1L ^ (-1L << SnowFlakeUUidUtils.datacenterIdBits);
|
|
|
// 毫秒内自增位
|
|
|
private final static long sequenceBits = 12L;
|
|
|
// 机器ID偏左移12位
|
|
|
- private final static long workerIdShift = sequenceBits;
|
|
|
+ private final static long workerIdShift = SnowFlakeUUidUtils.sequenceBits;
|
|
|
// 数据中心ID左移17位
|
|
|
- private final static long datacenterIdShift = sequenceBits + workerIdBits;
|
|
|
+ private final static long datacenterIdShift = SnowFlakeUUidUtils.sequenceBits + SnowFlakeUUidUtils.workerIdBits;
|
|
|
// 时间毫秒左移22位
|
|
|
- private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
|
|
|
+ private final static long timestampLeftShift = SnowFlakeUUidUtils.sequenceBits + SnowFlakeUUidUtils.workerIdBits + SnowFlakeUUidUtils.datacenterIdBits;
|
|
|
|
|
|
- private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
|
|
|
+ private final static long sequenceMask = -1L ^ (-1L << SnowFlakeUUidUtils.sequenceBits);
|
|
|
|
|
|
private final static Lock myLock = new ReentrantLock();
|
|
|
/* 上次生产id时间戳 */
|
|
@@ -53,95 +53,96 @@ public class SnowFlakeUUidUtils {
|
|
|
private static volatile SnowFlakeUUidUtils snowFlakeUUidUtils;
|
|
|
|
|
|
|
|
|
- private static SnowFlakeUUidUtils getSingleInstance(Long workerId, Long datacenterId){
|
|
|
- if(null == snowFlakeUUidUtils){
|
|
|
- synchronized (SnowFlakeUUidUtils.class){
|
|
|
- if(null == snowFlakeUUidUtils){
|
|
|
- if(null != workerId && null != datacenterId){
|
|
|
- snowFlakeUUidUtils = new SnowFlakeUUidUtils(workerId , datacenterId);
|
|
|
- }else{
|
|
|
- snowFlakeUUidUtils = new SnowFlakeUUidUtils();
|
|
|
+ private static SnowFlakeUUidUtils getSingleInstance(Long workerId, Long datacenterId) {
|
|
|
+ if (null == SnowFlakeUUidUtils.snowFlakeUUidUtils) {
|
|
|
+ synchronized (SnowFlakeUUidUtils.class) {
|
|
|
+ if (null == SnowFlakeUUidUtils.snowFlakeUUidUtils) {
|
|
|
+ if (null != workerId && null != datacenterId) {
|
|
|
+ SnowFlakeUUidUtils.snowFlakeUUidUtils = new SnowFlakeUUidUtils(workerId, datacenterId);
|
|
|
+ } else {
|
|
|
+ SnowFlakeUUidUtils.snowFlakeUUidUtils = new SnowFlakeUUidUtils();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return snowFlakeUUidUtils;
|
|
|
+ return SnowFlakeUUidUtils.snowFlakeUUidUtils;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param workerId 自定义的应用所在的服务器的机器ID,使用默认读取本机则无需传,传个NULL即可
|
|
|
+ * @param workerId 自定义的应用所在的服务器的机器ID,使用默认读取本机则无需传,传个NULL即可
|
|
|
* @param datacenterId 自定义的应用所在的服务器的数据中心ID,使用默认读取本机则无需传,传个NULL即可
|
|
|
- * @param preStr 自定义的ID前缀
|
|
|
- * **/
|
|
|
- public static String generaUUid(Long workerId, Long datacenterId , String preStr){
|
|
|
+ * @param preStr 自定义的ID前缀
|
|
|
+ **/
|
|
|
+ public static String generaUUid(Long workerId, Long datacenterId, String preStr) {
|
|
|
StringBuilder resultId = new StringBuilder();
|
|
|
- SnowFlakeUUidUtils snowFlakeUUidUtils = getSingleInstance(workerId , datacenterId);
|
|
|
- if(StringUtil.isNotEmpty(preStr)){
|
|
|
+ SnowFlakeUUidUtils snowFlakeUUidUtils = SnowFlakeUUidUtils.getSingleInstance(workerId, datacenterId);
|
|
|
+ if (StringUtil.isNotEmpty(preStr)) {
|
|
|
return resultId.append(preStr).append(snowFlakeUUidUtils.nextId()).toString();
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
return resultId.append(snowFlakeUUidUtils.nextId()).toString();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public SnowFlakeUUidUtils(){
|
|
|
- this.datacenterId = getDatacenterId(maxDatacenterId);
|
|
|
- this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
|
|
|
+ public SnowFlakeUUidUtils() {
|
|
|
+ this.datacenterId = SnowFlakeUUidUtils.getDatacenterId(SnowFlakeUUidUtils.maxDatacenterId);
|
|
|
+ this.workerId = SnowFlakeUUidUtils.getMaxWorkerId(datacenterId, SnowFlakeUUidUtils.maxWorkerId);
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
- * @param workerId
|
|
|
- * 工作机器ID
|
|
|
- * @param datacenterId
|
|
|
- * 序列号
|
|
|
+ * @param workerId 工作机器ID
|
|
|
+ * @param datacenterId 序列号
|
|
|
*/
|
|
|
public SnowFlakeUUidUtils(long workerId, long datacenterId) {
|
|
|
- if (workerId > maxWorkerId || workerId < 0) {
|
|
|
- throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
|
|
|
+ if (workerId > SnowFlakeUUidUtils.maxWorkerId || workerId < 0) {
|
|
|
+ throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", SnowFlakeUUidUtils.maxWorkerId));
|
|
|
}
|
|
|
- if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
|
|
- throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
|
|
|
+ if (datacenterId > SnowFlakeUUidUtils.maxDatacenterId || datacenterId < 0) {
|
|
|
+ throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", SnowFlakeUUidUtils.maxDatacenterId));
|
|
|
}
|
|
|
this.workerId = workerId;
|
|
|
this.datacenterId = datacenterId;
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* 获取下一个ID
|
|
|
* 线程安全
|
|
|
+ *
|
|
|
* @return NULL 抢锁失败,需要重新调用
|
|
|
- * 数字串 抢锁成功,则生成20位的数字串
|
|
|
+ * 数字串 抢锁成功,则生成20位的数字串
|
|
|
*/
|
|
|
- public Long nextId() {
|
|
|
+ public Long nextId() {
|
|
|
try {
|
|
|
|
|
|
- if(myLock.tryLock(700 , TimeUnit.MILLISECONDS)){
|
|
|
+ if (SnowFlakeUUidUtils.myLock.tryLock(700, TimeUnit.MILLISECONDS)) {
|
|
|
try {
|
|
|
long timestamp = timeGen();
|
|
|
- if (timestamp < lastTimestamp) {
|
|
|
- throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
|
|
+ if (timestamp < SnowFlakeUUidUtils.lastTimestamp) {
|
|
|
+ throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", SnowFlakeUUidUtils.lastTimestamp - timestamp));
|
|
|
}
|
|
|
|
|
|
- if (lastTimestamp == timestamp) {
|
|
|
+ if (SnowFlakeUUidUtils.lastTimestamp == timestamp) {
|
|
|
// 当前毫秒内,则+1
|
|
|
- sequence = (sequence + 1) & sequenceMask;
|
|
|
+ sequence = (sequence + 1) & SnowFlakeUUidUtils.sequenceMask;
|
|
|
if (sequence == 0) {
|
|
|
// 当前毫秒内计数满了,则等待下一秒
|
|
|
- timestamp = tilNextMillis(lastTimestamp);
|
|
|
+ timestamp = tilNextMillis(SnowFlakeUUidUtils.lastTimestamp);
|
|
|
}
|
|
|
} else {
|
|
|
sequence = 0L;
|
|
|
}
|
|
|
- lastTimestamp = timestamp;
|
|
|
+ SnowFlakeUUidUtils.lastTimestamp = timestamp;
|
|
|
// ID偏移组合生成最终的ID,并返回ID
|
|
|
- Long nextId = ((timestamp - twepoch) << timestampLeftShift)
|
|
|
- | (datacenterId << datacenterIdShift)
|
|
|
- | (workerId << workerIdShift) | sequence;
|
|
|
+ Long nextId = ((timestamp - SnowFlakeUUidUtils.twepoch) << SnowFlakeUUidUtils.timestampLeftShift)
|
|
|
+ | (datacenterId << SnowFlakeUUidUtils.datacenterIdShift)
|
|
|
+ | (workerId << SnowFlakeUUidUtils.workerIdShift) | sequence;
|
|
|
|
|
|
return nextId;
|
|
|
- }catch (Exception e){
|
|
|
- log.info("生成UUID抢锁失败:{}" , e);
|
|
|
- }finally {
|
|
|
- myLock.unlock();
|
|
|
+ } catch (Exception e) {
|
|
|
+ SnowFlakeUUidUtils.log.info("生成UUID抢锁失败:{}", e);
|
|
|
+ } finally {
|
|
|
+ SnowFlakeUUidUtils.myLock.unlock();
|
|
|
}
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
return null;
|
|
|
}
|
|
|
} catch (InterruptedException e) {
|
|
@@ -209,7 +210,7 @@ public class SnowFlakeUUidUtils {
|
|
|
}
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
- for(int i = 0; i < 20; i++){
|
|
|
+ for (int i = 0; i < 20; i++) {
|
|
|
|
|
|
System.out.println(SnowFlakeUUidUtils.generaUUid(null, null, null));
|
|
|
}
|