使用隊列(Queue)解決簡單的並發問題


有一個場景:一個搶購的項目,假設有5件商品,誰先搶到誰可以買,但是如果此時此刻(這里的此時此刻假設是相同的時間),有100人去搶這個商品,如果使用平時的方法會出現什么情況呢?你懂的,這里所說是就是有關並發的問題。

平時我們去超市購物去結賬的時候就是排隊,這里我們先讓搶購人排好隊,按時間,誰先點擊的搶購按鈕誰就排在前面,這樣就形成了一個隊列,然后我們再對這個隊列處理,這樣就不會出現並發的問題了。(至少可以處理這樣簡單的並發,這里不討論太復雜的並發)

案例:

 

要求:有一個發布文章的接口,每發布一篇文章,調用一下接口。(這里不用批量發布,為了講解這個)

 

建立一個這樣的處理程序類,BusinessInfoHelper.cs

 

[csharp]  view plain  copy
 
  1. namespace MyNameSpace   
  2.   
  3. {  
  4.     //隊列臨時類  
  5.     public class QueueInfo  
  6.     {  
  7.         public string medias { get; set; }  
  8.         public string proids { get; set; }  
  9.         public string host { get; set; }  
  10.         public string userid { get; set; }  
  11.         public string feedid { get; set; }  
  12.     }  
  13.   
  14.     public class BusinessInfoHelper  
  15.     {  
  16.         #region 解決發布時含有優質媒體時,前台頁面卡住的現象  
  17.         //原理:利用生產者消費者模式進行入列出列操作  
  18.   
  19.         public readonly static BusinessInfoHelper Instance = new BusinessInfoHelper();  
  20.         private BusinessInfoHelper()  
  21.         { }  
  22.   
  23.         private Queue<QueueInfo> ListQueue = new Queue<QueueInfo>();  
  24.   
  25.         public void AddQueue(string medias, string proids, string host, string userid, string feedid) //入列  
  26.         {  
  27.             QueueInfo queueinfo = new QueueInfo();  
  28.   
  29.             queueinfo.medias = medias;  
  30.             queueinfo.proids = proids;  
  31.             queueinfo.host = host;  
  32.             queueinfo.userid = userid;  
  33.             queueinfo.feedid = feedid;  
  34.             ListQueue.Enqueue(queueinfo);  
  35.         }  
  36.   
  37.         public void Start()//啟動  
  38.         {  
  39.             Thread thread = new Thread(threadStart);  
  40.             thread.IsBackground = true;  
  41.             thread.Start();  
  42.         }  
  43.   
  44.         private void threadStart()  
  45.         {  
  46.             while (true)  
  47.             {  
  48.                 if (ListQueue.Count > 0)  
  49.                 {  
  50.                     try  
  51.                     {  
  52.                         ScanQueue();  
  53.                     }  
  54.                     catch (Exception ex)  
  55.                     {  
  56.                         LO_LogInfo.WLlog(ex.ToString());  
  57.                     }  
  58.                 }  
  59.                 else  
  60.                 {  
  61.                     //沒有任務,休息3秒鍾  
  62.                     Thread.Sleep(3000);  
  63.                 }  
  64.             }  
  65.         }  
  66.   
  67.         //要執行的方法  
  68.         private void ScanQueue()  
  69.         {  
  70.             while (ListQueue.Count > 0)  
  71.             {  
  72.                 try  
  73.                 {  
  74.                     //從隊列中取出  
  75.                     QueueInfo queueinfo = ListQueue.Dequeue();  
  76.   
  77.                     //取出的queueinfo就可以用了,里面有你要的東西  
  78.                     //以下就是處理程序了  
  79.                     //。。。。。。  
  80.   
  81.                 }  
  82.                 catch (Exception ex)  
  83.                 {  
  84.                     throw;  
  85.                 }  
  86.             }  
  87.         }  
  88.  
  89.  
  90.         #endregion  
  91.     }  
  92. }  

 

以上頁面寫好后,在程序開始運行時就得啟動這個線程去不停的處理任務,那么我們在Global的Application_Start里可以這樣寫:

[csharp]  view plain  copy
 
  1. //啟動發布優質媒體程序  
  2. MyNameSpace.BusinessInfoHelper.Instance.Start();  


有一個問題出來了,如果我處理完隊列中的一條記錄后,想返回這條記錄的ID,這個程序好像不能完成,我就使用了另一個方法 Lock方法 ,把方法鎖定,具體的如下,

 

在頁面中定義全局的鎖:

[csharp]  view plain  copy
 
  1. private static object lockObject= new Object();  

 

在方法 中這樣調用:

[csharp]  view plain  copy
 
  1. lock(lockObject)  
  2.   
  3. {  
  4.   
  5. //........  
  6.   
  7. }  


如果不使用第二種方法的全局鎖,不知各位大俠有沒有好的解決辦法,如果有,可以跟貼,非常感謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM