c#中线程同步

c#中线程同步(Monitor方法)

这里只是学习笔记~

线程同步(Monitor方法)

   线程同步就是协调多个线程间的并发操作,以获得符合预期的、确定的执行结果,消除多线程应用程序执行中的不确定性,

它包含两个方面:1.保护资源(或代码),即确保资源(或代码)同时只能由一个线程(或指定个数的线程)访问,

                       一般措施是获取锁和释放锁(后面简称锁机制)

                      2.协调线程对资源(或代码)的访问顺序,即确定某一资源(或代码)只能先由线程T1访问,再由线程T2访问

                     一般措施是采用信号量(后面简称信号量机制)。当T2线程访问资源时,必须等待线程T1先访问,线程T1访问完后,发出信号量,通知线程T2可以访问。

1.使用对象本身作为锁对象

 Monitor.enter();

 xx();//有个缺陷,就是只能使用与引用类型, 解决方法 第二个

 Monitor.Exit()

2.使用System.Object作为锁对象(使用这种方式时,需要多创建一个无实际意义的,专用于协调线程的对象)

3.使用System.Type作为锁对象(使用System.Type对象是基于这样一个事实:多次调用typeof(Type)获取的是同一个对象)

线程异常!

在使用monitor的时候可能会出现这种情况,看代码!

    public  class Test
    {
        public  string called;
        public  void Record()
        {
                called += string.Format("{0}[{1}]", Thread.CurrentThread.Name, DateTime.Now.Millisecond);
                Console.WriteLine(called);
                throw new Exception(); // 模拟抛出了异常滴呀;
        }

    }

class Program
    {
         private Test t = new Test();
        static void Main(string[] args)
        {
           
            Program p = new Program();
            Thread.CurrentThread.Name = "main";
            ThreadStart st = new ThreadStart(p.ThreadEntry);
            Thread td = new Thread(st);
            td.IsBackground =false;                   
            td.Name = "worker";
            td.Start();
            p.ThreadEntry(); 
            Console.ReadLine();
        }

        void ThreadEntry()
        {
            try
            {
                Monitor.Enter(typeof(Test));
                t.Record();                //首先主线程抛出异常,直接到了catch语句中没有释放它占有的锁
                                           //子线程一直等待,
                Monitor.Exit(typeof(Test)); 
            }
            catch { }
            finally
            {
                //解决方法一
                //Monitor.Exit(typeof(Test));  写在finally中滴呀

                //解决方法二:
                //td.IsBackground =true; 设置为后台线程,当前台线程结束(main),后台线程就结束了
                //也不用带一种等待了滴呀;
               
            }
        }


    }

方法三:使用lock

     void ThreadEntry()
        {
            try
            {
                lock (typeof(Test))
                {
                    Test.Record();

                }
            }
            catch { }
            finally
                  { }
        }

 创建线程安全类型:将lock写在Test.Record()方法里面滴呀;

 但是lock方法的缺陷就是锁的粒度很小滴呀;

 下面我们进一步来探究。

原文地址:https://www.cnblogs.com/mc67/p/5116574.html