zoukankan      html  css  js  c++  java
  • 使用redis实现生产者消费者模式

      本次主要分享一下使用redis做缓存队列,实现生产者消费者模式。

      首先先来看一下redis提供的列表操作接口。像ListRightPush就和符合队列先进先出的原则。

      然后围绕这个列表已下单为例简要实现生产者和消费者两端的模块。

      生产者Controller

         IApplicationContext ctx = ContextRegistry.GetContext();
            /// <summary>
            /// 
            /// </summary>
            public void Order()
            {
                OrderRequest order = new OrderRequest { Mobile = "15100000001", GoodsName = "抱枕", Price = 1, OrderId = "1111" };
                Thread t1 = new Thread(new ParameterizedThreadStart(WriteQueue));
                t1.Start(order);
                order = new OrderRequest { Mobile = "15100000002", GoodsName = "坚果", Price = 2, OrderId = "1112" };
                Thread t2 = new Thread(new ParameterizedThreadStart(WriteQueue));
                t2.Start(order);
                order = new OrderRequest { Mobile = "15100000003", GoodsName = "羽绒服", Price = 3, OrderId = "1113" };
                Thread t3 = new Thread(new ParameterizedThreadStart(WriteQueue));
                t3.Start(order);
                order = new OrderRequest { Mobile = "15100000004", GoodsName = "阔腿裤", Price = 4, OrderId = "1114" };
                Thread t4 = new Thread(new ParameterizedThreadStart(WriteQueue));
                t4.Start(order);
                order = new OrderRequest { Mobile = "15100000005", GoodsName = "芒果", Price = 5, OrderId = "1115" };
                Thread t5 = new Thread(new ParameterizedThreadStart(WriteQueue));
                t5.Start(order);
                order = new OrderRequest { Mobile = "15100000006", GoodsName = "哑铃", Price = 6, OrderId = "1116" };
                Thread t6 = new Thread(new ParameterizedThreadStart(WriteQueue));
                t6.Start(order);
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="obj"></param>
            private void WriteQueue(Object obj)
            {
                //通过spring容器创建对象
                IBLLQueue BLLQueue = ctx.GetObject<BLLQueue>("IBLLQueue");
                BLLQueue.WriteRedisQueue((OrderRequest)obj);
            }   
        /// <summary>
        /// 订单对象
        /// </summary>
      public class OrderRequest
        {
            /// <summary>
            /// 订单Id
            /// </summary>
            public string OrderId { get; set; }
            /// <summary>
            /// 手机
            /// </summary>
            public string Mobile { get; set; }
            /// <summary>
            /// 物品名称
            /// </summary>
            public string GoodsName { get; set; }
            /// <summary>
            /// 价格
            /// </summary>
            public double Price { get; set; }
        }

      接口和实现类

     
       public interface IBLLQueue
        {
            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            void WriteRedisQueue(OrderRequest order);
        }
    
     public class BLLQueue : IBLLQueue
        {
            private string key = "OrderQueue";
            readonly static object _locker = new object();
            /// <summary>
            /// 
            /// </summary>
            /// <param name="WriteRedisQueue"></param>
            public void WriteRedisQueue(OrderRequest order)
            {
                //添加到下单队列
                lock (_locker)
                {
                    var json = JsonHelper.SerializeObject(order);
                    var result = (int)RedisService.ListRightSet(key, json);
                }
            }
        }

      redis帮助类

            /// <summary>
            /// ListGet
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static RedisValue[] ListGet(string key)
            {
                return Db.ListRange(key);
            }
            /// <summary>
            /// ListSet(尾)
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static long ListRightSet(string key, string value)
            {
                return Db.ListRightPush(key, value);
            }
            /// <summary>
            /// ListSet(头)
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static long ListLeftSet(string key, string value)
            {
                return Db.ListLeftPush(key, value);
            }
            /// <summary>
            /// ListRemove
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static long ListRemove(string key, string value)
            {
                return Db.ListRemove(key, value);
            }
            /// <summary>
            /// ListLength
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static long ListLength(string key)
            {
                return Db.ListLength(key);
            }

      运行方法,通过可视化工具可看到redis列表结果:

      2.通过控制台输出程序简单实现消费者模块。

      main函数:

          static void Main(string[] args)
            {
                Queue queue = new Queue();
                queue.run();
            }

      订单消费者实现方法:

     public class Queue
        {
            private string key = "OrderQueue";
            private bool flg = true;
            readonly static object _locker = new object();
            public void run()
            {
                try
                {
                    lock (_locker)
                    {
                        while (flg)
                        {
                            if (RedisService.ListLength(key) > 0)
                            {
                                Take();
                            }
                            flg = false;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            public void Take()
            {
                var list = RedisService.ListGet(key).ToList();
                foreach (var item in list)
                {
                    var order = JsonHelper.DeserializeJsonToObject<OrderRequest>(item);
                    if (order != null)
                    {
                        Console.WriteLine("订单编号:" + (order.OrderId ?? "") + "   物品名称:" + (order.GoodsName ?? "") + "   手机:" + (order.Mobile ?? "") + "   价格:" + order.Price);
                    }
                    //移除队列
                    RedisService.ListRemove(key, item);
                }
            }
    }

      执行结果:

      这样本次的案例就算小功告成。这边有简单使用spring.net。以前有使用过spring,年代久远,目前自己正在重新学习当中,往后再分享这一块学习心得。

  • 相关阅读:
    了解PCI Express的Posted传输与Non-Posted传输
    最强加密算法?AES加解密算法Matlab和Verilog实现
    校招必看硬核干货:IC前端这样学,秒变offer收割机!
    一次压力测试Bug排查-epoll使用避坑指南
    硬核干货 | C++后台开发学习路线
    Web服务器项目详解
    O准备如何苟进复赛圈?华为软挑开挂指南(附赛题预测)
    Linux最大文件句柄(文件描述符)限制和修改
    linux中对EINTR错误的处理
    C/C++实现单向循环链表(尾指针,带头尾节点)
  • 原文地址:https://www.cnblogs.com/baiyujing/p/8394671.html
Copyright © 2011-2022 走看看