Commit 61f477b7 authored by liuxingyu's avatar liuxingyu

雪花算法修改

parent 6ed9535a
......@@ -69,6 +69,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
......
......@@ -43,7 +43,7 @@ public class TestController {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String threadId = Thread.currentThread().getName() + Thread.currentThread().getId();
log.info("enter"+threadId+dateFormat.format(new Date()));
System.out.println(threadId+dateFormat.format(new Date()));
//redissonLockUtil.getLockByKey("265213225444411", LockType.FAIR_LOCK.value());
Tuple2<RLock, Boolean> rlocks = redissonLockUtil.tryLock(30000L, -1L, "265213225444411", LockType.REENTRANT_LOCK.value());
if (rlocks.getT2()) {
log.info(threadId + "拿锁成功"+ dateFormat.format(new Date()));
......@@ -83,7 +83,7 @@ public class TestController {
e.printStackTrace();
return new ResultForLock().error();
}finally {
redissonLockUtil.releaseLock("265213225444411", LockType.REENTRANT_LOCK.value());
redissonLockUtil.releaseLock(rlocks.getT1());
}
} else {
System.out.println("拿锁失败");
......@@ -126,7 +126,7 @@ public class TestController {
@PostMapping ("api/fair")
public ResultForLock<String> fair() {
String threadId = Thread.currentThread().getName() + Thread.currentThread().getId();
redissonLockUtil.getLockByKey("265213225444411", LockType.FAIR_LOCK.value());
// redissonLockUtil.getLockByKey("265213225444411", LockType.FAIR_LOCK.value());
Tuple2<RLock, Boolean> rlocks = redissonLockUtil.tryLock(20000L, -1L, "265213225444411", LockType.REENTRANT_LOCK.value());
if (rlocks.getT2()) {
System.out.println(threadId + "拿锁成功");
......@@ -139,7 +139,8 @@ public class TestController {
e.printStackTrace();
return new ResultForLock().error();
}finally {
redissonLockUtil.releaseLock("265213225444411", LockType.REENTRANT_LOCK.value());
rlocks.getT1().unlock();
// redissonLockUtil.releaseLock("265213225444411", LockType.REENTRANT_LOCK.value());
}
} else {
System.out.println("拿锁失败");
......
......@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
public class RedissonLockUtil {
public static final Long WAITTIME = 12000L;
public static final Long WAITTIME = 10000L;
public static final Long RELEASETIME = -1L;
@Autowired
......@@ -35,7 +35,7 @@ public class RedissonLockUtil {
* @param lockType REENTRANT_LOCK:可重入锁 FAIR_LOCK:公平锁 READ_LOCK:红锁 WRITE_LOCK:读写锁
* @return
*/
public RLock getLockByKey(String key, int lockType) {
public RLock getLockByKey(String key, int lockType) {
if (ObjectUtils.isEmpty(key)) {
key = Thread.currentThread().getName() + ":" + Thread.currentThread().getId();
}
......@@ -58,6 +58,7 @@ public class RedissonLockUtil {
/**
* 手动加锁,锁的有效期默认30秒
*
* @param rLock
*/
public void lock(RLock rLock) {
......@@ -66,6 +67,7 @@ public class RedissonLockUtil {
/**
* 手动解锁
*
* @param rLock
*/
public void unlock(RLock rLock) {
......@@ -76,15 +78,16 @@ public class RedissonLockUtil {
/**
* 当releaseTime传的是-1或者是空时,开启watch dog模式,会开启自动续锁
* 非阻塞式
*
* @param waitTime 等待时间
* @param releaseTime 锁有效时间
* @param key
* @param type
* @return
*/
public Tuple2<RLock,Boolean> tryLock(Long waitTime, Long releaseTime, String key, int type) {
public Tuple2<RLock, Boolean> tryLock(Long waitTime, Long releaseTime, String key, int type) {
boolean lock = false;
RLock rLock =null;
RLock rLock = null;
if (ObjectUtils.isEmpty(waitTime)) {
waitTime = WAITTIME;
}
......@@ -97,33 +100,32 @@ public class RedissonLockUtil {
} catch (Exception e) {
e.printStackTrace();
}
return Tuples.of(rLock,lock);
return Tuples.of(rLock, lock);
}
/**
* 手动释放 redissonLock 锁
*
* @param key
* @param rLock
* @return
*/
public boolean releaseLock(String key, int type) {
public boolean releaseLock(RLock rLock) {
String threadName = Thread.currentThread().getName() + ":" + Thread.currentThread().getId();
try {
RLock rLock = getLockByKey(key, type);
rLock.unlock();
if (!rLock.isLocked()) {
log.debug("已删除锁{}成功,当前线程:{}", key, threadName);
log.debug("已删除锁{}成功,当前线程:{}", rLock.getName(), threadName);
return true;
} else if (rLock.isHeldByCurrentThread()) {
log.debug("未删除锁{},还需当前线程解锁{}次,当前线程:{}", key, rLock.getHoldCount(), threadName);
log.debug("未删除锁{},还需当前线程解锁{}次,当前线程:{}", rLock.getName(), rLock.getHoldCount(), threadName);
return true;
} else {
log.warn("未删除锁{},还需其他线程解锁{}次,当前线程:{}", key, rLock.getHoldCount(), threadName);
log.warn("未删除锁{},还需其他线程解锁{}次,当前线程:{}", rLock.getName(), rLock.getHoldCount(), threadName);
return false;
}
} catch (Throwable e) {
log.error("解锁{}异常,返回false,当前线程:{}", key, threadName, e);
log.error("解锁{}异常,返回false,当前线程:{}", threadName, e);
return false;
}
}
......
package com.mushiny.redisson.utils;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.UUID;
import java.util.Random;
/**
* 描述信息
* 雪花算法的原理就是生成一个的 64 位比特位的 long 类型的唯一 id。开头一位固定0,41位时间戳,5位机器id,5位服务id,12位序号
*
* @auther lxy
* @since 2023/8/9 13:57
*/
@Component
public class SnowFlakeUtil {
/**
* 起始时间戳,从2023-08-01开始生成
*/
@Value("${snowflake.config.stamp:1690819200000L}")
private final static long START_STAMP = 1690819200000L;
/**
* 序列号占用的位数 12
*/
private final static long SEQUENCE_BIT = 22;
private final static long SEQUENCE_BIT = 12;
/**
* 机器标识占用的位数
......@@ -47,6 +51,7 @@ public class SnowFlakeUtil {
/**
* 机器标识
*/
@Value("${snowflake.config.machineId:160}")
private long machineId;
/**
* 序列号
......@@ -57,16 +62,18 @@ public class SnowFlakeUtil {
*/
private long lastStamp = -1L;
/**
* 构造方法
*
* @param machineId 机器ID
*/
public SnowFlakeUtil(long machineId) {
@Value("${snowflake.config.id.length:16")
private int length = 16;
@Value("${snowflake.config.id.strLength:16}")
private int strLength = 25;
public SnowFlakeUtil() {
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new RuntimeException("机器超过最大数量");
}
this.machineId = machineId;
}
/**
......@@ -89,22 +96,32 @@ public class SnowFlakeUtil {
// 不同毫秒内,序列号置为0
sequence = 0L;
}
lastStamp = currStamp;
return (currStamp - START_STAMP) << TIMESTAMP_LEFT // 时间戳部分
| machineId << MACHINE_LEFT // 机器标识部分
| sequence; // 序列号部分
return transferLength((currStamp - START_STAMP) << TIMESTAMP_LEFT | machineId << MACHINE_LEFT | sequence);
}
/**
* 产生下一个String类型的ID
* 产生下一个String类型的ID(随机5位字符串加上雪花算法id)
*/
public synchronized String nextStrId() {
String prefix = RandomUtil.randomString(5);
String netId = String.valueOf(nextId());
return prefix + netId;
long currStamp = getNewStamp();
if (currStamp < lastStamp) {
throw new RuntimeException("时钟后移,拒绝生成ID!");
}
if (currStamp == lastStamp) {
// 相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
// 同一毫秒的序列数已经达到最大
if (sequence == 0L) {
currStamp = getNextMill();
}
} else {
// 不同毫秒内,序列号置为0
sequence = 0L;
}
lastStamp = currStamp;
return transferLength(String.valueOf((currStamp - START_STAMP) << TIMESTAMP_LEFT | machineId << MACHINE_LEFT | sequence));
}
private long getNextMill() {
......@@ -120,4 +137,43 @@ public class SnowFlakeUtil {
}
/**
* Long类型id转换长度
*
* @param id
* @return
*/
private long transferLength(Long id) {
if (length < 20 && length > 15) {
id = Long.parseLong(StringUtils.rightPad(id.toString(), length, "0"));
}
if (length > 19) {
id = Long.parseLong(StringUtils.rightPad(id.toString(), 19, "0"));
}
return id;
}
/**
* String类型id转换长度
*
* @param id
* @return
*/
private String transferLength(String id) {
if (strLength > 16) {
id = RandomUtil.randomString(strLength - id.length()) + id;
}
return id;
}
public static void main(String[] args) {
SnowFlakeUtil snowFlakeUtil = new SnowFlakeUtil();
Long nextId = snowFlakeUtil.nextId();
String nextStrId = snowFlakeUtil.nextStrId();
System.out.println("Long类型的为" + nextId + "长度为" + nextId.toString().length());
System.out.println("String类型的为" + nextStrId + "长度为" + nextStrId.length());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment