`
chenzehe
  • 浏览: 538232 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

同步工具类之Semaphore 信号量

 
阅读更多

     Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。
     Semaphore实现的功能就类似厕所有5个坑,假如有十个人要上厕所,那么同时能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中的任何一个人让开后,其中在等待的另外5个人中又有一个可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。

    Semaphore在java.util.concurrent包下, 从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire() ,然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。说白了,Semaphore 是一个计数器,在计数器不为 0 的时候对线程就放行,一旦达到 0,那么所有请求资源的新线程都会被阻塞,包括增加请求到许可的线程,也就是说Semaphore不是可重入的。每一次请求一个许可都会导致计数器减少 1,同样每次释放一个许可都会导致计数器增加 1,一旦达到了 0,新的许可请求线程将被挂起。

 

构造方法:

public Semaphore(int permits)创建具有给定的许可数和非公平的公平设置的 Semaphore。 
public Semaphore(int permits,
                 boolean fair)创建具有给定的许可数和给定的公平设置的 Semaphore。 

主要方法:

void acquire() 
          从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。 
 void acquire(int permits) 
          从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。 
 void release() 
          释放一个许可,将其返回给信号量。 
 void release(int permits) 
          释放给定数目的许可,将其返回到信号量。 

 

    Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。例如,下面的类使用信号量控制对内容池的访问:

 class Pool {
   private static final int MAX_AVAILABLE = 100;
   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

   public Object getItem() throws InterruptedException {
     available.acquire();
     return getNextAvailableItem();
   }

   public void putItem(Object x) {
     if (markAsUnused(x))
       available.release();
   }

   // Not a particularly efficient data structure; just for demo

   protected Object[] items = ... whatever kinds of items being managed
   protected boolean[] used = new boolean[MAX_AVAILABLE];

   protected synchronized Object getNextAvailableItem() {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (!used[i]) {
          used[i] = true;
          return items[i];
       }
     }
     return null; // not reached
   }

   protected synchronized boolean markAsUnused(Object item) {
     for (int i = 0; i < MAX_AVAILABLE; ++i) {
       if (item == items[i]) {
          if (used[i]) {
            used[i] = false;
            return true;
          } else
            return false;
       }
     }
     return false;
   }

 }
 
 

    获得一项前,每个线程必须从信号量获取许可,从而保证可以使用该项。该线程结束后,将项返回到池中并将许可返回到该信号量,从而允许其他线程获取该项。注意,调用 acquire() 时无法保持同步锁,因为这会阻止将项返回到池中。信号量封装所需的同步,以限制对池的访问,这同维持该池本身一致性所需的同步是分开的。

    将信号量初始化为 1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。这通常也称为二进制信号量 ,因为它只能有两种状态:一个可用的许可,或零个可用的许可。按此方式使用时,二进制信号量具有某种属性(与很多 Lock 实现不同),即可以由线程释放“锁”,而不是由所有者(因为信号量没有所有权的概念)。在某些专门的上下文(如死锁恢复)中这会很有用。

    此类的构造方法可选地接受一个公平 参数。当设置为 false 时,此类不对线程获取许可的顺序做任何保证。特别地,闯入 是允许的,也就是说可以在已经等待的线程前为调用 acquire() 的线程分配一个许可,从逻辑上说,就是新线程将自己置于等待线程队列的头部。当公平设置为 true 时,信号量保证对于任何调用获取 方法的线程而言,都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。注意,FIFO 排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了 acquire ,但是却在该线程之后到达排序点,并且从方法返回时也类似。还要注意,非同步的 tryAcquire 方法不使用公平设置,而是使用任意可用的许可。

 

 

 

分享到:
评论

相关推荐

    使用信号量(Semaphore)实现线程的同步

    信号量(Semaphore)是...信号量是解决线程同步问题的一种高效工具,通过合理的信号量控制,可以有效地避免死锁、饥饿等问题,提高系统资源的利用率。理解并正确使用信号量,对于编写高效、稳定的多线程程序至关重要。

    信号量同步等待机制 semaphore wait-and-signal

    信号量(Semaphore)作为一种常用的同步工具,在此过程中扮演着重要角色。本文将详细介绍信号量的基本概念、工作原理以及如何通过信号量实现对临界资源的安全访问。 #### 二、临界资源与临界区 临界资源是指系统中...

    c++多线程同步——信号量

    信号量(Semaphore)是实现多线程同步的一种有效工具,常用于控制对共享资源的访问。在这个名为"Mthread11"的MFC工程中,我们可以看到如何在C++环境中应用信号量来解决多线程间的同步问题。 首先,我们需要理解什么...

    iOS GCD中级篇 - dispatch_semaphore(信号量)的理解及使用1

    信号量在多线程编程中扮演着协调和同步的角色,类似于锁,但它提供了更灵活的控制方式。 1. **信号量的基本概念** 信号量是一个整数值,可以用来限制同时访问特定资源的线程数量。当信号量的值大于0时,线程可以...

    2.线程间同步和通信之信号量(静态)

    STM32微控制器和RT-thread实时操作系统提供了丰富的机制来实现这一目标,其中信号量是常用的工具之一。本教程将深入探讨如何使用信号量进行线程间的同步和通信,特别是在STM32平台上的实践应用。 信号量,作为一种...

    使用信号量实现线程同步

    信号量(Semaphore)是实现线程同步的一种有效工具,它源于早期的计算机操作系统理论,由荷兰计算机科学家Dijkstra提出。在Windows系统中,信号量作为内核对象被广泛使用,可以用来控制对共享资源的访问。 信号量的...

    QT 下 信号量使用

    在QT框架中,信号量(Semaphore)是一种非常重要的同步机制,它源于进程间通信(IPC)的概念,并在多线程编程中广泛使用。信号量允许我们控制对共享资源的访问,确保同一时间只有一个线程或者有限数量的线程能够访问...

    rt-thread信号量_holecev_RT-Thread_rtthread信号量_信号量_

    在RT-Thread中,信号量(Semaphore)是多线程间同步和资源管理的重要工具,它允许线程之间进行协作,以实现对共享资源的有序访问。"holecev"可能是作者或项目的别名,而"RT-Thread_rtthread信号量_信号量_"则是强调...

    跨平台的C++线程模板类和信号量及互斥量模板类

    "Semaphore.h"文件很可能包含了跨平台的信号量实现,如`Semaphore`类,可能有如下操作: ```cpp Semaphore(int initialCount); void acquire(); bool try_acquire(); void release(); ``` `acquire`用于获取信号量...

    semaphore控制多线程循序执行

    总之,Semaphore是一种强大的同步工具,能够帮助我们在多线程环境中实现复杂的数据访问控制策略。理解并熟练运用Semaphore,对于编写高效、安全的多线程代码至关重要。在实际编程中,应根据具体需求选择合适的同步...

    Java进程信号量机制的实验程序

    Java进程信号量机制是多线程编程中一种有效的同步工具,它源于操作系统中的同步原语,用于管理和控制对共享资源的访问。在Java中,信号量由`java.util.concurrent.Semaphore`类实现,它提供了两种类型:可重用的二...

    qt5多线程,信号量,互斥量,等待条件

    本文将详细探讨如何利用QT5的线程机制,以及信号量(Semaphore)、互斥量(Mutex)和等待条件(Condition Variable)等同步原语,来构建一个高效的生产者-消费者模型。 首先,我们要理解线程的基本概念。线程是程序...

    C#信号量,用于多线程

    ### C#中的信号量Semaphore与多线程管理 在探讨C#中的`Semaphore`类之前,我们先简单回顾一下多线程的基本概念。在计算机科学领域,多线程是指一个程序内部可以同时运行多个线程(即执行路径),每个线程都可以独立...

    有关水果问题的信号量程序

    信号量机制是操作系统中一种重要的同步工具,常用于解决多线程环境中的资源竞争问题。本问题中,通过“爸爸放苹果,妈妈放橘子,盘子只能容纳两个水果。儿子只吃苹果,女儿只吃橘子”的情景,我们可以深入理解信号量...

    VXWORKS实时操作系统中信号量用于多任务同步与互斥的讨论.pdf

    信号量(Semaphore)是操作系统中用于多任务同步和互斥的机制之一,其基本思想是通过一个或多个信号量变量来控制对共享资源的访问。信号量可以被看作是一个计数器,用来表示资源的可用数。当任务需要访问共享资源时...

    JAVA 多线程之信号量(Semaphore)实例详解

    **JAVA 多线程之信号量Semaphore实例详解** 在Java多线程编程中,信号量Semaphore是一种非常重要的同步工具,用于控制对公共资源的访问。Semaphore类位于`java.util.concurrent`包下,它允许我们限制同时访问特定...

    java同步互斥信号量问题

    在Java中,我们可以使用`java.util.concurrent.Semaphore`类来实现信号量。创建一个信号量时,可以指定初始许可证的数量。以下是一个简单的示例: ```java import java.util.concurrent.Semaphore; public class ...

    无名信号量示例代码

    总结起来,无名信号量是Linux系统编程中一种强大的同步工具,它可以确保多个线程安全、有序地访问共享资源。理解和熟练使用无名信号量对于编写高效、可靠的多线程程序至关重要。通过阅读提供的链接和实践相关的示例...

    VC线程信号量的使用举例

    在VC++环境中,我们通常使用Windows API来管理线程的同步和通信,其中信号量(Semaphore)就是一种常用工具。本文将通过一个简单的VC线程信号量使用例子来介绍其工作原理和应用。 信号量是一种同步机制,用于控制对...

    UCOSII实验2-信号量和邮箱_STM32ucos_

    **信号量(Semaphore)** 信号量是一种同步原语,用于控制多个任务对共享资源的访问。在UCOSII中,信号量分为二进制信号量和计数信号量两种类型。二进制信号量只有0和1两个状态,用于控制互斥访问;计数信号量则可以...

Global site tag (gtag.js) - Google Analytics