多线程demo

背景描述,一个商城网站,一个订单支付方案有多个1.金额支付2.积分支付3.工资支付(分期和全额),所以一个订单的方案可能有1;有1、2,或1、2、3

状态,1.订单状态,2,支付状态==>多方案的订单有多个支付状态。

问题发现,一个订单多次支付!!!

于是分析,找解决方案。

1.DB 行锁

2.多线程控制

多线程测试参考 链接

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleThread
{
    class Program
    {
        const string firstOrderId = "001";
        const string secondOrderId = "002";
        const string thirdOrderId = "003";
        static void Main(string[] args)
        {
            test(LockType.LockObject);
            test(LockType.LockStaticObject);
            test(LockType.LockString);
            test(LockType.LockThis);
        }
        static void test(LockType lockType)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("----------------测试相同的订单-------------------");
            Console.ForegroundColor = ConsoleColor.Green;
            OrderPay(firstOrderId, 1, lockType);
            OrderPay(firstOrderId, 2, lockType);
            OrderPay(firstOrderId, 3, lockType);

            Thread.Sleep(1000);

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("----------------测试不同的订单-------------------");
            Console.ForegroundColor = ConsoleColor.Green;
            OrderPay(firstOrderId, 1, lockType);
            OrderPay(secondOrderId, 1, lockType);
            OrderPay(thirdOrderId, 1, lockType);

        }

        static void OrderPay(string orderId, int threadNo, LockType lockType)
        {
            new Thread(() => new Payment(orderId, threadNo).Pay(lockType)).Start();
            Thread.Sleep(100);
        }
    }

    public class Payment
    {
        private readonly string LockString;
        private readonly int ThreadNo;
        private readonly Object LockObj = new object();
        private static readonly Object StaticLockObj = new object();

        public Payment(string orderId, int threadNo)
        {
            this.LockString = orderId;
            this.ThreadNo = threadNo;
        }

        public void Pay(LockType lockType)
        {
            ShowMessage("等待资源");
            switch (lockType)
            {
                case LockType.LockThis:
                    lock (this)
                    {
                        ShowAction();
                    }
                    break;
                case LockType.LockString:
                    lock (LockString)
                    {
                        ShowAction();
                    }
                    break;
                case LockType.LockObject:
                    lock (LockObj)
                    {
                        ShowAction();
                    }
                    break;
                case LockType.LockStaticObject:
                    lock (StaticLockObj)
                    {
                        ShowAction();
                    }
                    break;
                default:
                    break;
            }
            ShowMessage("释放资源");
        }
        private void ShowAction()
        {
            ShowMessage("进入锁并开始操作");
            Thread.Sleep(1000);
            ShowMessage("完成操作,时间" + DateTime.Now);
        }
        private void ShowMessage(string message)
        {
            Console.WriteLine(string.Format("订单{0}的第{1}个线程{2}", LockString, ThreadNo, message));
        }
    }
    public enum LockType
    {
        LockThis = 0,
        LockString = 1,
        LockObject = 2,
        LockStaticObject = 3
    }
}
View Code

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleThread2
{
    class Program
    {
        /// <summary>
        /// 订单号
        /// </summary>
        const string firstOrderId = "d001";
        const string secondOrderId = "d002";
        const string thirdOrderId = "d003";
        const string fourthOrderId = "d004";
        const string fivthOrderId = "d005";
        static void Main(string[] args)
        {
            Test();
        }
        static void Test()
        {
            ConsoleOut.WriteWhite("----------------测试-------------------");
            //相同的订单 一个一个来
            OrderPay(firstOrderId, 1);
            OrderPay(firstOrderId, 2);
            OrderPay(firstOrderId, 3);
            OrderPay(firstOrderId, 4);
            //不同的订单可以同时处理
            OrderPay(secondOrderId, 5);
            OrderPay(thirdOrderId, 6);
            OrderPay(fourthOrderId, 7);
            OrderPay(fivthOrderId, 8);
        }
        /// <summary>
        /// 多线程支付
        /// </summary>
        /// <param name="orderId">订单号</param>
        /// <param name="threadNo">线程编号</param>
        static void OrderPay(string orderId, int threadNo)
        {
            new Thread((object x) => Payment.Pay(new object[] { orderId, threadNo })).Start();
        }
    }
    /// <summary>
    /// 锁字典一个订单对映一个锁
    /// </summary>
    public static class DicLockManage
    {
        /// <summary>
        /// 根据订单id得到,锁资源
        /// </summary>
        public static Dictionary<string, object> dicLock = new Dictionary<string, object>();
        /// <summary>
        /// 字典操作的锁
        /// </summary>
        public static readonly object objLock = new object();
        /// <summary>
        /// 得到订单锁
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetKeyValue(string key)
        {
            lock (objLock)
            {
                if (dicLock.ContainsKey(key))
                {
                    return dicLock[key];
                }
                else
                {
                    dicLock.Add(key, new object());
                    return GetKeyValue(key);
                }
            }
        }
    }
    /// <summary>
    /// 订单支付类
    /// </summary>
    public static class Payment
    {
        /// <summary>
        /// 模拟支付方法
        /// </summary>
        /// <param name="objParams"></param>
        public static void Pay(object[] objParams)
        {
            object[] Params = objParams as object[];
            string OrderId = Params[0].ToString();
            int ThreadNo = Convert.ToInt32(Params[1]);
            //加锁
            lock (DicLockManage.GetKeyValue(OrderId))
            {
                ShowMessage(OrderId, ThreadNo, "等待资源");
                ShowAction(OrderId, ThreadNo);//模拟支付
                ShowMessage(OrderId, ThreadNo, "释放锁");
            }
        }
        private static void ShowAction(string OrderId, int ThreadNo)
        {
            ShowMessage(OrderId, ThreadNo, "进入锁并开始操作");
            ConsoleOut.WriteRed("线程" + ThreadNo + "处理中...");
            Thread.Sleep(3000);
            ConsoleOut.WriteGreen("线程" + ThreadNo + "完成处理...");
            ShowMessage(OrderId, ThreadNo, "完成操作,时间" + DateTime.Now);
        }
        private static void ShowMessage(string OrderId, int ThreadNo, string message)
        {
            ConsoleOut.WriteYellow(string.Format("订单{0}的第{1}个线程{2}", OrderId, ThreadNo, message));
        }
    }
    /// <summary>
    /// 输出类,设置颜色
    /// </summary>
    public static class ConsoleOut
    {
        public static void WriteWhite(string message)
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(message);
        }
        public static void WriteRed(string message)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message);
        }
        public static void WriteYellow(string message)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(message);
        }
        public static void WriteGreen(string message)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(message);
        }
    }
}

测试图

1.同一个订单多个线程访问,一个个处理

2.多个订单多个线程,可以一起处理,完成的时间一样

3.同时运行

如有问题,请指出。

posted on 2016-05-13 16:14  Aidou_dream  阅读(2255)  评论(3编辑  收藏  举报

导航