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();