C# 线程同步之Moitor实现线程的顺序执行

有这么个场景,A线程执行A函数,B线程执行B函数,C线程执行C函数,并且ABC函数要按顺序执行,如何实现

我们可以利用Monitor和ConcurrentDictionary来实现。

Monitor是比lock更灵活操作,再.net中,lock在中间语言会被翻译成Monitor;

ConcurrentDictionary是线程安全的字典。

实现一个类:

   /// <summary>
    /// 顺序线程 线程按执行顺序
    /// </summary>
    public class OrderedThread
    {
        #region 静态字段

        /// <summary>
        /// 当前的线程循序序号
        /// </summary>
        private static int _inner_orderedID = 0;

        /// <summary>
        /// 当前的线程的队列
        /// </summary>
        private static ConcurrentDictionary<int, OrderedThread> inner_readyThreadList = new ConcurrentDictionary<int, OrderedThread>();

        /// <summary>
        /// 线程锁
        /// </summary>
        private static object _objLock = new object();

        #endregion

        #region 成员字段

        /// <summary>
        /// 处理的委托
        /// </summary>
        private Action<int> _inner_action = null;

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="handling">处理的委托</param>
        public OrderedThread(Action<int> handling)
        {
            this._inner_action = handling;
        }

        #endregion

        #region 开始执行线程

        /// <summary>
        /// 开始执行线程
        /// </summary>
        public void Start()
        {
            //添加到就绪集合中
            inner_readyThreadList.AddOrUpdate(_inner_orderedID++, this, (key, vlaue) =>
            {
                return this;
            });

            Thread th = new Thread(() =>
            {
                bool isEnter = Monitor.TryEnter(_objLock);
                if (isEnter)
                {
                    //如果就绪队列中有要执行的线程
                    while (inner_readyThreadList.Count() > 0)
                    {
                        //找到起始的最小值
                        int minIndex = inner_readyThreadList.Keys.Min();

                        //绪队列中线程执行
                        inner_readyThreadList[minIndex]._inner_action.Invoke(minIndex);

                        //移除执行完成的
                        OrderedThread orderedThreadTmp = null;
                        inner_readyThreadList.TryRemove(minIndex, out orderedThreadTmp);
                    }

                    Monitor.Exit(_objLock);
                }
            });
            th.SetApartmentState(ApartmentState.STA);
            th.IsBackground = true;
            th.Start();
        }

        #endregion
    }

我们的业务类:

    public class PrintClass 
    {
        public void PrintOne() 
        {
            Console.WriteLine("one");
        }

        public void PrintTwo()
        {
            Console.WriteLine("two");
        }

        public void PrintThree()
        {
            Console.WriteLine("three");
        }

    }

调用:

 class Program
    {
        static void Main(string[] args)
        {
            PrintClass p=new PrintClass();

            OrderedThread firstThread = new OrderedThread((o)=> {
                p.PrintOne();
                Thread.Sleep(5000);
            });

            OrderedThread SecondThread = new OrderedThread((o) => {
                p.PrintTwo();

            });

            OrderedThread ThirdThread = new OrderedThread((o) => {
                p.PrintThree();

            });

            firstThread.Start();
            ThirdThread.Start();

            SecondThread.Start();



            Console.ReadLine();
        }
    }

其中:Start的顺序就是要执行的顺序。

posted @ 2020-08-21 11:22  卖雨伞的小男孩  阅读(545)  评论(0编辑  收藏  举报