• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

有这么个场景,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的顺序就是要执行的顺序。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
c#WinFormMenu自动生成发布时间:2022-07-13
下一篇:
DLLImport在C#中的用法发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap