• 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方法的缺陷就是锁的粒度很小滴呀;

     下面我们进一步来探究。

  • 相关阅读:
    javascript 拷贝详解
    javascript 递归函数详解
    移动端布局解决方案
    Flexbox
    CSS中越界问题的经典解决方案
    移动应用测试方法与思路
    不是人家太装逼,而是我们太low
    GUI自动化测试策略
    GUI测试稳定性的关键技术
    GUI测试还能这么玩(Page Code Gen + Data Gen + Headless)
  • 原文地址:https://www.cnblogs.com/mc67/p/5116574.html
Copyright © 2020-2023  润新知