C# 线程同步之排它锁/Monitor监视器类

一、Monitor类说明,提供同步访问对象的机制。

1.位于System.Threading命名空间下,mscorlib.dll程序集中。

2.Monitor通过获取和释放排它锁的方式实现多线程的同步问题。

3.Monitor实现当前进程内的多线程的同步,和lock语句的功能类似。

4.当前为静态类,使用简单

5.依赖的锁定对象和lock语句中类似,同样需要引用类型、建议私有、只读、静态

定义代码:

    //
    // 摘要:
    //     提供同步访问对象的机制。
    [ComVisible(true)]
    public static class Monitor

二、常用方法说明

1.Enter(obj)方法 在指定对象上获取排它锁。

2.Exit(obj)   释放指定对象上的排他锁。

3.IsEntered(obj) 判断当前线程是否已经持有排它锁

4.TryEnter(object obj, TimeSpan timeout)  在指定的时间量内尝试获取指定对象上的排他锁。

5.Wait(object obj) 释放对象上的锁并阻止当前线程,直到它重新获取该锁。

6.Pulse(object obj) 通知等待队列中的线程锁定对象状态的更改。

7.PulseAll(object obj)  通知所有的等待线程对象状态的更改。

三、示例说明一:

说明:多线程累加数值,解决同步问题

private readonly static object _MyLock = new object();
static int Count = 0;
static void CountAdd()
{
    Monitor.Enter(_MyLock); //获取排它锁
    Count++;
    Console.WriteLine(Count);
    if (Count == 10)
    {
        Count = 0;
    }
    Monitor.Exit(_MyLock); //释放排它锁
}
public static void TestOne()
{
    //启动4个线程,累加Count
    for (int i = 0; i < 4; i++)
    {
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                CountAdd();
                Thread.Sleep(500 * i);
            }
        });
    }
}

1.如果不使用排它锁处理,会出现数据异常

2.使用锁定结果会正常

四、借助于using(){} 块实现锁定处理

1.此场景在事务处理中可能会用到,保证同一个事务,如果一个线程开启操作,其他线程对当前事务操作等待。

2.此场景对于外部使用,不需要考虑多线程问题

1.继承了IDisposable接口的封装

    class AddHelper : IDisposable
    {

        private readonly static object _MyLock = new object();
        static int Count = 0;
        public AddHelper()
        {
            //启用排它锁
            Monitor.Enter(_MyLock);
        }
        public void AddCount()
        {
            Count++;
            Console.WriteLine(Count);
            if (Count == 10)
            {
                Count = 0;
            }
        }
        public void Dispose()
        {
            //释放排它锁
            Monitor.Exit(_MyLock);
        }
    }

2.调用代码块

public static void TestTwo()
{
    //启动4个线程,累加Count
    for (int i = 0; i < 4; i++)
    {
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                //如果不使用排他锁处理,会出现数据异常
                //AddHelper _add = new AddHelper();
                //_add.AddCount();

                //将排他锁处理封装
                using (AddHelper _add = new AddHelper())
                {
                    _add.AddCount();
                }
                Thread.Sleep(500 * i);
            }
        });
    }
}

更多参考:

C# lock关键词/lock语句块、线程锁

C# using 关键字使用整理

EntiryFramework中事务操作(二)

官方参考:https://msdn.microsoft.com/zh-cn/library/system.threading.monitor.aspx

时间: 2024-11-03 05:33:54

C# 线程同步之排它锁/Monitor监视器类的相关文章

线程同步 – lock和Monitor

在多线程代码中,多个线程可能会访问一些公共的资源(变量.方法逻辑等等),这些公共资源称为临界区(共享区):临界区的资源是不安全,所以需要通过线程同步对多个访问临界区的线程进行控制. 同样,有些时候我们需要多个线程按照特定的顺序执行,这时候,我们也需要进行线程同步. 下面,我们就看看C#中通过lock和Monitor进行线程同步. lock关键字 lock是一种非常简单而且经常使用的线程同步方式,lock 关键字将语句块标记为临界区. lock 确保当一个线程位于代码的临界区时,另一个线程不能进入

C#编程总结(三)线程同步

C#编程总结(三)线程同步 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力.否则,在完全满足前一个请求之前,将无法处理每个新请求.然而,线程的异步特性意味着必须协调对资源(如文件句柄.网络连接和内存)的访问.否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作. "如果觉得有用,请帮顶! 如果有

[转]C#编程总结(三)线程同步

本文转自:http://www.cnblogs.com/yank/p/3227324.html 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力.否则,在完全满足前一个请求之前,将无法处理每个新请求.然而,线程的异步特性意味着必须协调对资源(如文件句柄.网络连接和内存)的访问.否则,两个或更多的线程可能在同一时间访问相同的资源,

Visual C++线程同步技术剖析:临界区,事件,信号量,互斥量

转自: 使线程同步 在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作.更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解.正常情况下对这种处理结果的了解应当在其处理任务完成后进行. 如果不采取适当的措施,其他线程往往会在线程处理任务结束前就去访问处理结果,这就很有可能得到有关处理结果的错误了解.例如,多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题.如果一个线程负责改变此变量的值,而其他线程负责同时读取变量内容,则不能保证读取到的数

【转】多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上)

本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过 本篇的介绍能对常见的线程同步方法有一个整体的认识,而对每种方式的使用细节,适用场合不会过多解释.让我们来看看这几个类的关系图: 1.lock关键字      lock是C#关键词,它将语句块标记为临界区,确保当一个线程位于代码的临界区时,另一个线程不进入临界区.如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放.方法是获取给定

C#并行编程-线程同步原语(Barrier,CountdownEvent,ManualResetEventSlim,SemaphoreSlim,SpinLock,SpinWait,Monitor,volatile)

菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 背景 有时候必须访问变量.实例.方法.属性或者结构体,而这些并没有准备好用于并发访问,或者有时候需要执行部分代码,而这些代码必须单独运行,这是不得不通过将任务分解的方式让它们独立运行. 当任务和线程要访问共享的数据和资源的时候,您必须添加显示的同步,或者使用原子操作或锁. 之前的.NET Framework提供了昂贵的锁机制以及遗留的多线程模型,新的数据结构允许细粒度的并发和并行化,并且降低一定必要的开销,这些数据结

多线程 - 线程同步锁(lock、Monitor)

1. 前言 多线程编程的时候,我们不光希望两个线程间能够实现逻辑上的先后顺序运行,还希望两个不相关的线程在访问同一个资源的时候,同时只能有一个线程对资源进行操作,否则就会出现无法预知的结果. 比如,有两个线程需要对同一个计数器加1,我们希望结果是计数器最终加2,但可能同时获取到了这个计数器,第一个线程对计数器加1,但第二个线程并不知道,于是重新对计数器加1,导致最终计数器损失了一个计数.为了解决这个问题,就必须在获取该计数器前锁定,防止其他线程再次获取,直到处理完成后再释放. Monitor.l

C#多线程:深入了解线程同步lock,Monitor,Mutex,同步事件和等待句柄(中)

本篇继续介绍WaitHandler类及其子类 Mutex,ManualResetEvent,AutoResetEvent的用法..NET中线程同步的方式多的让人看了眼花缭乱,究竟该怎么去理解呢?其实,我们抛开.NET环境看线程同步,无非是执行两种操作:一是互斥/加锁,目的是保证临界区代码操作的"原子性":另一种是信号灯操作,目的是保证多个线程按照一定顺序执行,如生产者线程要先于消费者线程执行..NET中线程同步的类无非是对这两种方式的封装,目的归根结底都可以归结为实现互斥/ 加锁或者是

C#线程同步技术(二) Interlocked 类

接昨天谈及的线程同步问题,今天介绍一个比较简单的类,Interlocked.它提供了以线程安全的方式递增.递减.交换和读取值的方法. 它的特点是: 1.相对于其他线程同步技术,速度会快很多. 2.只能用于简单的同步问题. 比叫好理解,不再赘述,给一个我们常用的单例模式的 Interlocked 实现: class SourceManager { private SourceManager() { } private static SourceManager sourceManager; publ