Browse Source

Snowflake 循环等待下一个时间时加入对时钟倒退的判断

Snowflake 在循环等待下一个时间时,判断时间未发生变化的方式由<=改为==,避免了时钟突然倒退导致的长时间循环,同时加入时钟倒退检测,避免生成重复ID
jptx1234 5 years ago
parent
commit
a3eca85e12
1 changed files with 7 additions and 1 deletions
  1. 7 1
      hutool-core/src/main/java/cn/hutool/core/lang/Snowflake.java

+ 7 - 1
hutool-core/src/main/java/cn/hutool/core/lang/Snowflake.java

@@ -177,9 +177,15 @@ public class Snowflake implements Serializable {
 	 */
 	 */
 	private long tilNextMillis(long lastTimestamp) {
 	private long tilNextMillis(long lastTimestamp) {
 		long timestamp = genTime();
 		long timestamp = genTime();
-		while (timestamp <= lastTimestamp) {
+		// 循环直到操作系统时间戳变化
+		while (timestamp == lastTimestamp) {
 			timestamp = genTime();
 			timestamp = genTime();
 		}
 		}
+		if (timestamp < lastTimestamp) {
+			// 如果发现新的时间戳比上次记录的时间戳数值小,说明操作系统时间发生了倒退,报错
+			throw new IllegalStateException(
+					StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", lastTimestamp - timestamp));
+		}
 		return timestamp;
 		return timestamp;
 	}
 	}