在弄電商類網站的時候,往往是根據年月日時分秒的格式生成訂單號(yyyyMMddHHmmss),為了解決並發性,就直接在生成訂單號的區域塊加上lock。 下面,我們來簡單測試一下。 1.新建項目(控制台應用程序) 2.新建一個類:OrderIdHelper.cs /// <summary> /// 訂單助手 /// </summary> class OrderIdHelper { private static readonly object Locker = new object(); private static string _tempId = ""; /// <summary> /// 生成訂單編號 /// </summary> public static void GenerateId() { lock (Locker) //lock 關鍵字可確保當一個線程位於代碼的臨界區時,另一個線程不會進入該臨界區。 { var orderId = "Wen" + DateTime.Now.ToString("yyyyMMddHHmmss"); //年月日時分秒 if (string.Equals(_tempId, orderId)) { throw new Exception("訂單號重復!"); } _tempId = orderId; Console.WriteLine(orderId); } } } 3.Program.cs class Program { static void Main(string[] args) { //創建包含兩個線程的數組 var threads = new Thread[2] { new Thread(OrderIdHelper.GenerateId), new Thread(OrderIdHelper.GenerateId), }; foreach (var thread in threads) { //線程啟動 thread.Start(); } Console.Read(); } } 4.結果:=====OrderIdDemo_1.rar 點我下載===== 5.發現一個不錯的訂單號生成規則,稍作改動: 不重復訂單號生成規則(原網址) /// <summary> /// 訂單助手 /// </summary> public class OrderHelper { /// <summary> /// 防止創建類的實例 /// </summary> private OrderHelper() { } private static readonly object Locker = new object(); private static int _sn = 0; /// <summary> /// 生成訂單編號 /// </summary> /// <returns></returns> public static string GenerateId() { lock (Locker) //lock 關鍵字可確保當一個線程位於代碼的臨界區時,另一個線程不會進入該臨界區。 { if (_sn == int.MaxValue) { _sn = 0; } else { _sn++; } Thread.Sleep(100); return "Wen" + DateTime.Now.ToString("yyyyMMddHHmmss")+ _sn.ToString().PadLeft(10, '0'); } } } 6.關於使用GUID的個人見解。 ①不清楚生成的時間,不方便管理。 ②官方解釋:GUID 是一個 128 位整數(16 字節),可用於所有需要唯一標識符的計算機和網絡。 此標識符重復的可能性非常小。
1