/// <summary> /// 申请锁,每间隔 4 次调用 1 次 Thread.Sleep(0),用于高频高冲突场景(不检测休眠标识,和 SpinLock.Enter4 效果一样) /// </summary> public void EnterNotCheckSleepFlag() { do { if (System.Threading.Interlocked.CompareExchange(ref lockValue, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref lockValue, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref lockValue, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref lockValue, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref lockValue, 1, 0) == 0) { return; } System.Threading.Thread.Sleep(0); }while (true); }
/// <summary> /// 申请锁,每间隔 4 次调用 1 次 Thread.Sleep(0),用于高频一般冲突场景 /// </summary> public void EnterYield() { do { if (System.Threading.Interlocked.CompareExchange(ref Lock, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref Lock, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref Lock, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref Lock, 1, 0) == 0) { return; } ThreadYield.YieldOnly(); if (System.Threading.Interlocked.CompareExchange(ref Lock, 1, 0) == 0) { return; } System.Threading.Thread.Sleep(0); }while (true); }
/// <summary> /// 获取下一个ID /// </summary> /// <returns></returns> public long GetNext() { while (System.Threading.Interlocked.CompareExchange(ref identityLock, 1, 0) != 0) { ThreadYield.YieldOnly(); } long timestamp = startTimestamp + Date.TimestampDifference; if (timestamp < maxTimestamp) { long identity = (currentIdentity += identityIncrement); if ((identity & mask) != 0) { System.Threading.Interlocked.Exchange(ref identityLock, 0); return(identity); } if (--timestampCount == 0) { maxTimestamp += Date.MillisecondTimestampDifferencePerSecond; timestampCount = 1000; } maxTimestamp += Date.TimestampPerMillisecond; System.Threading.Interlocked.Exchange(ref identityLock, 0); return(identity); } else if (timestamp == maxTimestamp) { long identity = (((currentIdentity >> bits) + 1) << bits) | distributed; if (--timestampCount == 0) { maxTimestamp += Date.MillisecondTimestampDifferencePerSecond; timestampCount = 1000; } currentIdentity = identity; maxTimestamp += Date.TimestampPerMillisecond; System.Threading.Interlocked.Exchange(ref identityLock, 0); return(identity); } else { long identity = Date.GetMillisecondsByTimestamp(timestamp), lastIdentity = currentIdentity >> bits; while (identity <= lastIdentity) { ++identity; } timestampCount = 1000; maxTimestamp = Date.GetTimestampByMilliseconds(identity + 1); currentIdentity = (identity = (identity << bits) | distributed); System.Threading.Interlocked.Exchange(ref identityLock, 0); return(identity); } }