From 1f04d3ad5cb176de35d9910cbd4d5b838d3098a1 Mon Sep 17 00:00:00 2001
From: hueifeng <695979933@qq.com>
Date: Thu, 19 Oct 2023 22:49:32 +0800
Subject: [PATCH] Removed lock and implemented SpinWait and Interlocked for
enhanced performance
---
.../Properties/launchSettings.json | 12 ++++++
Snowflake/SnowFlake.cs | 37 ++++++++++---------
2 files changed, 31 insertions(+), 18 deletions(-)
create mode 100644 Snowflake.Redis.Sample/Properties/launchSettings.json
diff --git a/Snowflake.Redis.Sample/Properties/launchSettings.json b/Snowflake.Redis.Sample/Properties/launchSettings.json
new file mode 100644
index 0000000..ab2191f
--- /dev/null
+++ b/Snowflake.Redis.Sample/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "profiles": {
+ "Snowflake.Redis.Sample": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:57871;http://localhost:57872"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Snowflake/SnowFlake.cs b/Snowflake/SnowFlake.cs
index ca1b760..fd541de 100644
--- a/Snowflake/SnowFlake.cs
+++ b/Snowflake/SnowFlake.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
namespace Snowflake
{
@@ -51,52 +52,52 @@ public SnowFlake(long datacenterId, long machineId)
_machineId = machineId;
}
- readonly object _lock = new object();
-
///
/// 产生下一个ID
///
///
public virtual long NextId()
{
- lock (_lock)
+ while (true)
{
- long currStamp = GetNewStamp();
-
- if (currStamp < _lastStamp)
+ long timestamp = GetNewStamp();
+ if (timestamp < _lastStamp)
{
//时钟回拨,更新为上一次生成id的时间戳
- currStamp = _lastStamp;
- //throw new Exception("Clock moved backwards. Refusing to generate id");
+ timestamp = _lastStamp;
}
- if (currStamp == _lastStamp)
+ if (_lastStamp == timestamp)
{
//相同毫秒内,序列号自增
_sequence = (_sequence + 1) & MaxSequence;
//同一毫秒的序列数已经达到最大
if (_sequence == 0L)
{
- currStamp = GetNextMill();
+ SpinWait.SpinUntil(() => GetNewStamp() > _lastStamp);
+ continue;
}
}
else
{
//不同毫秒内,序列号置为0
- _sequence = 0;
+ _sequence = 0L;
}
- _lastStamp = currStamp;
-
- var id = ((currStamp - StartStamp) << TimestampLeft) //时间戳部分
- | (_datacenterId << DatacenterLeft) //数据中心部分
- | (_machineId << MachineLeft) //机器标识部分
- | _sequence; //序列号部分
+ if (Interlocked.CompareExchange(ref _lastStamp, timestamp, timestamp) != timestamp)
+ {
+ continue;
+ }
- return id;
+ // Bits for timestamp, data center, machine identifier, and sequence number
+ return ((timestamp - StartStamp) << TimestampLeft)
+ | (_datacenterId << DatacenterLeft)
+ | (_machineId << MachineLeft)
+ | _sequence;
}
}
+
protected virtual long GetNextMill()
{
long mill = GetNewStamp();