在弄電商類網站的時候,往往是根據年月日時分秒的格式生成訂單號(yyyyMMddHHmmss),為了解決並發性,就直接在生成訂單號的區域塊加上lock。
下面,我們來簡單測試一下。
1.新建項目(控制台應用程序)
2.新建一個類:OrderIdHelper.cs

1 /// <summary> 2 /// 訂單助手 3 /// </summary> 4 class OrderIdHelper 5 { 6 private static readonly object Locker = new object(); 7 private static string _tempId = ""; 8 9 /// <summary> 10 /// 生成訂單編號 11 /// </summary> 12 public static void GenerateId() 13 { 14 lock (Locker) //lock 關鍵字可確保當一個線程位於代碼的臨界區時,另一個線程不會進入該臨界區。 15 { 16 var orderId = "Wen" + DateTime.Now.ToString("yyyyMMddHHmmss"); //年月日時分秒 17 18 if (string.Equals(_tempId, orderId)) 19 { 20 throw new Exception("訂單號重復!"); 21 } 22 23 _tempId = orderId; 24 25 Console.WriteLine(orderId); 26 } 27 } 28 }
3.Program.cs

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //創建包含兩個線程的數組 6 var threads = new Thread[2] 7 { 8 new Thread(OrderIdHelper.GenerateId), 9 new Thread(OrderIdHelper.GenerateId), 10 }; 11 12 foreach (var thread in threads) 13 { 14 //線程啟動 15 thread.Start(); 16 } 17 18 Console.Read(); 19 } 20 }
4.結果:=====OrderIdDemo_1.rar 點我下載=====
5.發現一個不錯的訂單號生成規則,稍作改動: 不重復訂單號生成規則(原網址)
1 /// <summary> 2 /// 訂單助手 3 /// </summary> 4 public class OrderHelper 5 { 6 /// <summary> 7 /// 防止創建類的實例 8 /// </summary> 9 private OrderHelper() { } 10 11 private static readonly object Locker = new object(); 12 private static int _sn = 0; 13 14 /// <summary> 15 /// 生成訂單編號 16 /// </summary> 17 /// <returns></returns> 18 public static string GenerateId() 19 { 20 lock (Locker) //lock 關鍵字可確保當一個線程位於代碼的臨界區時,另一個線程不會進入該臨界區。 21 { 22 if (_sn == int.MaxValue) 23 { 24 _sn = 0; 25 } 26 else 27 { 28 _sn++; 29 } 30 31 Thread.Sleep(100); 32 33 return "Wen" + DateTime.Now.ToString("yyyyMMddHHmmss")+ _sn.ToString().PadLeft(10, '0'); 34 } 35 } 36 }
6.關於使用GUID的個人見解。
①不清楚生成的時間,不方便管理。
②官方解釋:GUID 是一個 128 位整數(16 字節),可用於所有需要唯一標識符的計算機和網絡。 此標識符重復的可能性非常小。<==詳見MSDN文檔==>