zoukankan      html  css  js  c++  java
  • (C#)使用队列(Queue)解决简单的并发问题

    有一个场景:一个抢购的项目,如果有5件商品。谁先抢到谁能够买,可是如果此时此刻(这里的此时此刻如果是同样的时间),有100人去抢这个商品,如果使用平时的方法会出现什么情况呢?你懂的。这里所说是就是有关并发的问题。

    平时我们去超市购物去结账的时候就是排队,这里我们先让抢购人排好队,按时间,谁先点击的抢购button谁就排在前面,这样就形成了一个队列,然后我们再对这个队列处理。这样就不会出现并发的问题了。

    (至少能够处理这样简单的并发,这里不讨论太复杂的并发)

    案例:

    要求:有一个公布文章的接口。每公布一篇文章,调用一下接口。

    (这里不用批量公布,为了解说这个)

    建立一个这种处理程序类,BusinessInfoHelper.cs

    namespace MyNameSpace 
    
    {
        //队列暂时类
        public class QueueInfo
        {
            public string medias { get; set; }
            public string proids { get; set; }
            public string host { get; set; }
            public string userid { get; set; }
            public string feedid { get; set; }
        }
    
        public class BusinessInfoHelper
        {
            #region 解决公布时含有优质媒体时。前台页面卡住的现象
            //原理:利用生产者消费者模式进行入列出列操作
    
            public readonly static BusinessInfoHelper Instance = new BusinessInfoHelper();
            private BusinessInfoHelper()
            { }
    
            private Queue<QueueInfo> ListQueue = new Queue<QueueInfo>();
    
            public void AddQueue(string medias, string proids, string host, string userid, string feedid) //入列
            {
                QueueInfo queueinfo = new QueueInfo();
    
                queueinfo.medias = medias;
                queueinfo.proids = proids;
                queueinfo.host = host;
                queueinfo.userid = userid;
                queueinfo.feedid = feedid;
                ListQueue.Enqueue(queueinfo);
            }
    
            public void Start()//启动
            {
                Thread thread = new Thread(threadStart);
                thread.IsBackground = true;
                thread.Start();
            }
    
            private void threadStart()
            {
                while (true)
                {
                    if (ListQueue.Count > 0)
                    {
                        try
                        {
                            ScanQueue();
                        }
                        catch (Exception ex)
                        {
                            LO_LogInfo.WLlog(ex.ToString());
                        }
                    }
                    else
                    {
                        //没有任务,歇息3秒钟
                        Thread.Sleep(3000);
                    }
                }
            }
    
            //要运行的方法
            private void ScanQueue()
            {
                while (ListQueue.Count > 0)
                {
                    try
                    {
                        //从队列中取出
                        QueueInfo queueinfo = ListQueue.Dequeue();
    
                        //取出的queueinfo就能够用了,里面有你要的东西
                        //下面就是处理程序了
                        //。

    。。。

    。 } catch (Exception ex) { throw; } } } #endregion } }

    以上页面写好后。在程序開始执行时就得启动这个线程去不停的处理任务,那么我们在Global的Application_Start里能够这样写:

    //启动公布优质媒体程序
    MyNameSpace.BusinessInfoHelper.Instance.Start();
    


    有一个问题出来了。假设我处理完队列中的一条记录后。想返回这条记录的ID,这个程序好像不能完毕。我就使用了还有一个方法 Lock方法 ,把方法锁定,详细的例如以下,

    在页面中定义全局的锁:

    private static object lockObject= new Object();
    
    

    在方法 中这样调用:

    lock(lockObject)
    
    {
    
    //........
    
    }
    
    


    假设不使用另外一种方法的全局锁,不知各位大侠有没有好的解决的方法,假设有,能够跟贴,很感谢。

  • 相关阅读:
    上传图片,将图片保存在腾讯云(2种方式)
    由ping所引发的思考~
    php面试上机题(2018-3-3)
    【八】jqeury之click事件[添加及删除数据]
    【七】jquery之属性attr、 removeAttr、prop[全选全不选及反选]
    【六】jquery之HTML代码/文本/值[下拉列表框、多选框、单选框的选中]
    【五】jquery之事件(focus事件与blur事件)[提示语的出现及消失时机]
    小白懂算法之基数排序
    mysql_sql199语法介绍
    Python基本编程快速入门
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7294979.html
Copyright © 2011-2022 走看看