• 监视器


    监视器

    Monitor 对象通过使用 Monitor.Enter、Monitor.TryEnter 和 Monitor.Exit 方法对特定对象进行加锁和解锁来提供同步访问代码区域的功能。 对代码区域加锁之后,可以使用 Monitor.Wait、Monitor.Pulse 和 Monitor.PulseAll 方法。 Wait 在其暂停并等待通知的情况下解锁。 当 Wait 收到通知时,会返回并重新加锁。 Pulse 和PulseAll 都发送信号以继续执行等待队列中的下一个线程。

    lock语句使用Monitor.Enter获取锁,使用Monitor.Exit释放锁。使用lock的优点在于块中的所有内容包含在Try语句中,Try语句有一个finally块用于保证锁得以释放。

    Monitor将锁定对象(引用类型)而非值类型。如果将值类型传递给Enter和Exit时,它会针对每个调用分别装箱。 由于每个调用都创建一个单独的对象,所以 Enter 从不拦截,此外,传递给 Exit 的对象不同于传递给 Enter 的对象,所以 Monitor 将引发 SynchronizationLockException

    虽然您可以在调用 Enter 和 Exit 之前装箱值类型变量,并将相同的装箱对象同时传递给两个方法,但是这样做没有任何好处。 对变量的更改不能在装箱的变量中体现出来,也没有办法更改已装箱的变量的值。

    一个Demo:

    namespace MyConsole2
    {
        class Program
        {
            static Int32 numAsyncOps = 5;
            static AutoResetEvent asyncOpsAreDone = new AutoResetEvent(false);
            static SyncResource SyncRes = new SyncResource();
            static UnSyncResource UnSyncRes = new UnSyncResource();
    
            static void Main(string[] args)
            {
                for (Int32 threadNum = 0; threadNum < 5; threadNum++)
                {
                    //ThreadPool.QueueUserWorkItem(new WaitCallback(SyncUpdateResource), threadNum);
                    ThreadPool.QueueUserWorkItem(new WaitCallback(UnSyncUpdateResource), threadNum);
                }
    
                asyncOpsAreDone.WaitOne();//阻塞当前现在,直到WaitHandler收到信号
                Console.WriteLine("	
    All synchronized operations have completed.	
    ");
    
                Console.ReadLine();
            }
    
    
            static void SyncUpdateResource(Object state)
            {
                // This calls the internal synchronized method, passing
                // a thread number.
                SyncRes.Access((Int32)state);
    
                // Count down the number of methods that the threads have called.
                // This must be synchronized, however; you cannot know which thread
                // will access the value **before** another thread's incremented
                // value has been stored into the variable.
                if (Interlocked.Decrement(ref numAsyncOps) == 0)
                {
                    // Announce to Main that in fact all thread calls are done.
                    asyncOpsAreDone.Set();//将事件状态设置为终止状态
                }
            }
    
            static void UnSyncUpdateResource(Object state)
            {
                // This calls the unsynchronized method, passing a thread number.
                UnSyncRes.Access((Int32)state);
    
                // Count down the number of methods that the threads have called.
                // This must be synchronized, however; you cannot know which thread
                // will access the value **before** another thread's incremented
                // value has been stored into the variable.
                if (Interlocked.Decrement(ref numAsyncOps) == 0)
                {
                    // Announce to Main that in fact all thread calls are done.
                    asyncOpsAreDone.Set();
                }
            }
    
        }
        class SyncResource
        {
            public void Access(Int32 threadNum)
            {
                // Uses Monitor class to enforce synchronization.
                lock (this)
                {
                    // Synchronized: Despite the next conditional, each thread
                    // waits on its predecessor.
                    if (threadNum % 2 == 0)
                    {
                        Thread.Sleep(2000);
                    }
                    Console.WriteLine("Start Synched Resource access (Thread={0})", threadNum);
                    Thread.Sleep(200);
                    Console.WriteLine("Stop Synched Resource access  (Thread={0})", threadNum);
                }
            }
        }
    
        // Without the lock, the method is called in the order in which threads reach it.
        class UnSyncResource
        {
            public void Access(Int32 threadNum)
            {
                // Does not use Monitor class to enforce synchronization.
                // The next call throws the thread order.
                if (threadNum % 2 == 0)
                {
                    Thread.Sleep(2000);
                }
                Console.WriteLine("Start UnSynched Resource access (Thread={0})", threadNum);
                Thread.Sleep(200);
                Console.WriteLine("Stop UnSynched Resource access  (Thread={0})", threadNum);
            }
        }
    }
  • 相关阅读:
    SQL Server 服务由于登录失败而无法启动
    一个项目涉及到的50个Sql语句
    sql server2008 数据库镜像的问题
    C# 根据枚举名(string)获得enum中的枚举值
    在不同版本的 IIS 上使用 ASP.NET MVC(转)
    sqlite 默认当前时间
    Nginx反向代理后防盗链设置
    JavaScript 图片加载
    nginx配置文件中的location中文详解
    程序设计的十个做与不做
  • 原文地址:https://www.cnblogs.com/goodlucklzq/p/4487268.html
Copyright © 2020-2023  润新知