在线做静态头像的网站,注册一个公司需要哪些资料,2019年新电商法做网站,长沙网站建设0731C#开发者(面试者)都会遇到lock(Monitor)#xff0c;Mutex#xff0c;Semaphore#xff0c;SemaphoreSlim这四个与锁相关的C#类型#xff0c;本文期望以最简洁明了的方式阐述四种对象的区别。什么是线程安全教条式理解如果代码在多线程环境中运行的结果与单线程运行结果一样… C#开发者(面试者)都会遇到lock(Monitor)MutexSemaphoreSemaphoreSlim这四个与锁相关的C#类型本文期望以最简洁明了的方式阐述四种对象的区别。什么是线程安全教条式理解如果代码在多线程环境中运行的结果与单线程运行结果一样其他变量值也和预期是一样的那么线程就是安全的结合场景理解两个线程都为集合增加元素我们错误的理解即使是多线程也总有先后顺序吧集合的两个位置先后塞进去就完了实际上集合增加元素这个行为看起来简单实际并不一定是原子操作。在添加一个元素的时候它可能会有两步来完成在 Items[Size] 的位置存放此元素增大 Size 的值。在单线程运行的情况下如果 Size 0添加一个元素后此元素在位置0之后设置Size1如果是在多线程场景下有两个线程线程A先将元素存放在位置0但是此时CPU调度线程A暂停线程B得到运行机会线程B也向此ArrayList添加元素因为此时Size仍然等于0 注意哦我们假设添加元素是经过两个步骤而线程A仅仅完成了步骤1所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行都增加 Size 的值。那好我们来看看ArrayList的情况元素实际上只有一个存放在位置 0而Size却等于2形成了脏数据这种就定义为对ArrayList的新增元素操作是线程不安全的。线程安全这个问题不单单存在于集合类我们始终要记得Never ever modify a shared resource by multipie threads unless resource is thread-safe.我们对SqlServerMongodb对HttpContext的访问都会涉及thread-safe。- 利用C# mongodb driver操作Mongo打包时常用操作是线程安全的Only a few of the C# Driver classes are thread safe. Among them: MongoServer, MongoDatabase, MongoCollection and MongoGridFS.- 对于HttpContext 静态属性的操作是线程安全的Any public static members of this type HttpContext are thread safe any instance members are not guaranteed to be thread safe.各语言推出了适用于不同范围的线程同步技术来预防以上脏数据实现线程安全线程同步技术话不多说给出大图四象限对象的区别支持线程进入的个数是否跨进程支持 上半区 lockMonitor, Mutex中文称为互斥锁都只支持单线程进入被保护代码其他线程则必须等待进入的线程完成 {Critical Section}下半区SemaphoreSlim、Semaphore中文称为信号量支持并发多线程进入被保护代码对象在初始化时会指定 最大信号灯数量当线程请求访问资源信号量递减而当他们释放时信号量计数又递增。左半区lock (Monitor)、SemaphoreSlim 是CRL对象 进程内线程同步 右半区MutexSemaphore都继承自WaitHandle对象支持命名是内核对象在系统级别能支持进程间线程同步。进程间线程同步不多见分布式锁的场景越来越多这里按下不表啰嗦一下常见的进程内线程同步技术 ① lockMonitor开发者最常用的lock关键字使用方式相当简单对于单进程内线程同步相当有效实际上lock是Monitor的语法糖实际的编译代码如下object __lockObj x;bool __lockWasTaken false;try{ System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken); // Your code...}finally{ if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);}一般使用私有静态对象作为lockMonitor线程同步的同步对象那配合lock完成代码锁定的那个对象到底起什么作用呢 这里面有个SyncBlockIndex的概念新建的托管堆在内存表现如下 每个堆对象函数表指针这也是一个重要知识点用于在多态中判断对象到底是哪个类型、同步块索引、对象字段其中同步块索引是lock解决线程同步的关键SyncBlockIndex是一个地址指针传送门新创建的对象objLock,其SyncBlockindex -1,不指向任何有效同步块调用静态类Monitor.Enter(objLock), CRL会寻找一个空闲SyncBlock并将objLock对象的SyncBlockIndex指向该块 例如上图中ObjectAObjectC的SyncBlockIndex指向了2个SyncBlockExit(objLock)会将objLock对象的SyncBlockIndex重新赋为 -1 释放出来的SyncBlock可以在将来被其他对象SyncBlockIndex引用。② lockMonitor vs SemaphoreSlim 两者都是进程内线程同步技术SemaphoreSlim信号量支持多线程进入另外SemaphoreSlim 有异步等待方法支持在异步代码中线程同步,解决在async code中无法使用lock语法糖的问题// 实例化单信号量static SemaphoreSlim semaphoreSlim new SemaphoreSlim(1,1);// 异步等待进入信号量如果没有线程被授予对信号量的访问权限则进入执行保护代码否则此线程将在此处等待直到信号量被释放为止await semaphoreSlim.WaitAsync();try{ await Task.Delay(1000);}finally{ // 任务准备就绪后释放信号灯。【准备就绪时始终释放信号量】至关重要否则我们将获得永远被锁定的信号量 semaphoreSlim.Release();}总结从宏观上掌握Monitor,Mutex,SemaphoreSlim,Semaphore的区别有利于形成【线程同步知识体系】文章着重记录进程内线程同步技术。