Selaa lähdekoodia

解决 sequence 非毫秒内并发偶数居多问题

jobob 8 vuotta sitten
vanhempi
commit
ccbe049233

+ 9 - 2
mybatis-plus/src/main/java/com/baomidou/mybatisplus/toolkit/Sequence.java

@@ -18,6 +18,7 @@ package com.baomidou.mybatisplus.toolkit;
 import java.lang.management.ManagementFactory;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
+import java.util.concurrent.ThreadLocalRandom;
 
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
@@ -149,17 +150,23 @@ public class Sequence {
         }
 
         if (lastTimestamp == timestamp) {
+            // 相同毫秒内,序列号自增
             sequence = (sequence + 1) & sequenceMask;
             if (sequence == 0) {
+                // 同一毫秒的序列数已经达到最大
                 timestamp = tilNextMillis(lastTimestamp);
             }
         } else {
-            sequence = 0L;
+            // 不同毫秒内,序列号置为 0 - 9 随机数
+            sequence = ThreadLocalRandom.current().nextLong(0,9);
         }
 
         lastTimestamp = timestamp;
 
-        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;
+        return ((timestamp - twepoch) << timestampLeftShift)    // 时间戳部分
+                | (datacenterId << datacenterIdShift)           // 数据中心部分
+                | (workerId << workerIdShift)                   // 机器标识部分
+                | sequence;                                     // 序列号部分
     }
 
     protected long tilNextMillis(long lastTimestamp) {

+ 17 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/IdWorkerTest.java

@@ -90,4 +90,21 @@ public class IdWorkerTest {
 		Assert.assertTrue(even >= low && even <= high);
 	}
 
+	@Test
+	public void test1() throws Exception {
+		// 毫秒内并发
+		for (int i = 0; i < 1000; i++) {
+			System.out.println(IdWorker.getId());
+		}
+	}
+
+
+	@Test
+	public void test2() throws Exception {
+		// 随机尾数
+		for (int i = 0; i < 1000; i++) {
+			Thread.sleep(10);
+			System.out.println(IdWorker.getId());
+		}
+	}
 }