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)
    
    {
    
    //........
    
    }
    
    


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

  • 相关阅读:
    windows 按时自动化任务
    Linux libusb 安装及简单使用
    Linux 交换eth0和eth1
    I.MX6 GPS JNI HAL register init hacking
    I.MX6 Android mmm convenient to use
    I.MX6 GPS Android HAL Framework 调试
    Android GPS GPSBasics project hacking
    Python windows serial
    【JAVA】别特注意,POI中getLastRowNum() 和getLastCellNum()的区别
    freemarker跳出循环
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7294979.html
Copyright © 2011-2022 走看看