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 @   卖雨伞的小男孩  阅读(566)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示