线程同步的情景之二

简介:

    情景一中,我主要介绍了用于解决资源争用时各种方式的区别,本篇文章我们将进一步介绍线程同步的第二种场景。

 

 情景二:数量有限,先到先得

 

  情景简介:与情景一类似,但是这次茅坑的数量不只一个。如果有需求的人数少于茅坑数量,那一切都很和谐。但是人数超过茅坑数量的时候该怎么办?多个人占用一个坑?

  解决办法:当所有茅坑都客满的时候,其他人必须乖乖等在外面,只有当有人从里面出来的时候,下一个人才能进去。

  问题抽象:当某一资源同一时刻允许一定数量的线程使用的时候,需要有个机制来阻塞多余的线程,直到资源再次变得可用。

  线程同步方案:Semaphore、SemaphoreSlim

  方案特性:限量供应;除所有者外,其他人无条件等待;先到先得(谁先进茅坑,谁先用,没有先后顺序

 

  各方案间的区别

  Semaphore 的中文名称叫信号量,在学操作系统的时候肯定都会讲到。而扯到信号量,最常拿来举的就是生产者与消费者的例子。与上一篇一样,我不会在这里重复介绍一些网上多的是的内容,大家如果有兴趣,可以自己去找度娘、必硬或谷哥。

  在继续阅读前,请确保你已经对用户模式构造、内核模式构造和混合模式构造有所了解,如果尚未了解,建议您先阅读情景一中相关章节。

 

内核模式(kernal-mode)

  Semaphore 通过在构造函数中传入容器大小来限制一次性允许访问的线程数量。与情景一介绍中的 Mutex 一样属于内核模式,而且都拥有同一个祖宗:WaitHandle。但是与 Mutex 不一样的是,通过线程一获取的所有权,可以由线程二来释放。下面的写法是完全合法的。

复制代码
    Task.Factory.StartNew(() =>
    {
        //类似于消费者
        semaphore.WaitOne();
        Thread.Sleep(5000);
    });
 
    Thread.Sleep(1000);
    Task.Factory.StartNew(() =>
    {
        //类似于生产者
        semaphore.Release();
    });
复制代码

 

  优点:提供数量限制的能力,可以跨进程使用。

    //进程一
    Semaphore s = new Semaphore(1, 1, "myname", out creaded);
     
    //进程二
    Semaphore s = Semaphore.OpenExisting("myname");

  缺点:速度慢于用户模式、混合模式构造,稍快于 mutex。

 

 

混合模式(hybrid-mode)

  SemaphoreSlim 是 .Net 4.0 时引进的一个新类型,使用方式上类似 Semaphore,是轻量级的 Semaphore。不允许跨进程使用。

  优点:提供数量限制的能力;速度快,优于 Semaphore。

  缺点:不能跨进程使用。

 

总 结

  本篇文章介绍的方法主要用于解决资源有限(数量大于一)时线程同步的问题。如果资源唯一,那利用 Semaphore s = new Semaphore(1,1) 的效果与创建一个 Mutex 的效果实际是一致的。而此时的 Semaphore 会有一个新名称叫 Binary Semaphore (二元信号量)。

 

  那什么时候该使用 Semaphore, 什么时候使用 Mutex? 

  记住本系列强调的情景!如果用于资源争用,请使用 Mutex;如果用于限量使用请使用 Semaphore。







本文转自stg609博客园博客,原文链接:http://www.cnblogs.com/stg609/p/4050483.html,如需转载请自行联系原作者

目录
相关文章
|
4月前
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
71 1
|
存储 安全 Java
Java并发编程学习4-线程封闭和安全发布
本篇介绍 对象的共享之线程封闭和安全发布
82 2
Java并发编程学习4-线程封闭和安全发布
|
7月前
|
缓存 安全 Java
多线程--深入探究多线程的重点,难点以及常考点线程安全问题
多线程--深入探究多线程的重点,难点以及常考点线程安全问题
158 1
|
数据采集 算法 安全
深入探究进程、线程和协程:并发编程的三重境界
深入探究进程、线程和协程:并发编程的三重境界
|
安全 算法 Java
【并发编程技术】「技术辩证分析」在并发编程模式下进行线程安全以及活跃性问题简析
【并发编程技术】「技术辩证分析」在并发编程模式下进行线程安全以及活跃性问题简析
80 0
【并发编程技术】「技术辩证分析」在并发编程模式下进行线程安全以及活跃性问题简析
|
存储 SQL 安全
搞定|通过实际案例搞懂多任务线程
搞定|通过实际案例搞懂多任务线程
搞定|通过实际案例搞懂多任务线程
|
存储 缓存 监控
Java并发编程系列之二线程基础
上篇文章对并发的理论基础进行了回顾,主要是为什么使用多线程、多线程会引发什么问题及引发的原因,和怎么使用Java中的多线程去解决这些问题。
Java并发编程系列之二线程基础
|
安全 C++
模拟生产者-消费者问题和读者-写者问题
模拟生产者-消费者问题和读者-写者问题
397 0
模拟生产者-消费者问题和读者-写者问题
|
Java 调度
Java并发编程程系列之二:多线程实现的三种方式
多线程处理是Java中处理并发任务非常重要的手段。本文主要介绍了多线程实现的几种方式以及每种实现方式优缺点,以供大家在实际开发中可以根据实际的应用场景进行自由选择。 继承Thread 实现Runnable接口 实现Callable接口
Java并发编程程系列之二:多线程实现的三种方式
|
Java 程序员
一个多线程死锁案例,如何避免及解决死锁问题?
多线程死锁在java程序员笔试的时候时有遇见,死锁概念在之前的文章有介绍,大家应该也都明白它的概念,不清楚的去翻看历史文章吧。
219 0
一个多线程死锁案例,如何避免及解决死锁问题?