一、概念

Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目。

一个信号量有且仅有3种操作,且它们全部是原子的:初始化、增加和减少 
增加可以为一个进程解除阻塞; 
减少可以让一个进程进入阻塞。

和线程池的区别:使用Seamphore,创建了多少线程,实际就会有多少线程进行执行,只是可同时执行的线程数量会受到限制。但使用线程池,不管你创建多少线程,实际可执行的线程数是一定的。

二、方法

1 构造方法:

Semaphore(int)、Semaphore(int,boolean)

int表示该信号量拥有的许可数量

boolean表示获取许可的时候是否是公平的。(公平指的是先来的先执行)

2 获取许可

acquire()、acquire(int)、tryAcquire()

int参数表示一次性要获取几个许可,默认为1个,acquire方法在没有许可的情况下,要获取许可的线程会阻塞。

tryAcquire()方法在没有许可的情况下会立即返回 false,要获取许可的线程不会阻塞。

3 释放许可

release()、release(int)

int参数表示一次性要释放几个许可,默认为1个,

注意一个线程调用release()之前并不要求一定要调用了acquire因此如果释放的比获取的信号量还多,例如获取了2个,释放了5次,那么当前信号量就动态的增加为5了(实现动态增加)

4 当前可用的许可数

int availablePermits()

三、测试

public void testSemaphore()
{
    // 线程池
    ExecutorService exec = Executors.newCachedThreadPool();
    // 只能5个线程同时访问
    final Semaphore semp = new Semaphore(2);
    // 模拟20个客户端访问
    for (int index = 0; index < 5; index++) {
        final int NO = index;
        Runnable run = new Runnable() {
            @Override
            public void run() {
                try {
                    if (semp.availablePermits() > 0) {
                        System.out.println( NO + "线程启动");
                    else {
                        System.out.println(NO + "线程启动,排队等待");
                    }
                    // 获取许可
                    semp.acquire();
                    System.out.println(NO + "线程执行" );
                    //模拟实际业务逻辑
                    Thread.sleep((long) (Math.random() * 10000));
                    // 访问完后,释放
                    semp.release();
                    System.out.println(NO + "线程释放");
                catch (InterruptedException e) {
                }
            }
        };
        exec.execute(run);
    }
 
    try {
        Thread.sleep(10);
    catch (InterruptedException e) {
        e.printStackTrace();
    }
 
    //System.out.println(semp.getQueueLength());
 
 
 
    // 退出线程池
    exec.shutdown();
}

0线程启动
0线程执行
1线程启动
1线程执行
2线程启动,排队等待
3线程启动,排队等待
4线程启动,排队等待
2线程执行
0线程释放
1线程释放
3线程执行
2线程释放
4线程执行
3线程释放
4线程释放

 

信号量Semaphore的使用的更多相关文章

  1. C# 多线程之一:信号量Semaphore

    通过使用一个计数器对共享资源进行访问控制,Semaphore构造器需要提供初始化的计数器(信号量)大小以及最大的计数器大小 访问共享资源时,程序首先申请一个向Semaphore申请一个许可证,Sema ...

  2. 经典线程同步 信号量Semaphore

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  3. 互斥锁Mutex与信号量Semaphore的区别

    转自互斥锁Mutex与信号量Semaphore的区别 多线程编程中,常常会遇到这两个概念:Mutex和Semaphore,两者之间区别如下: 有人做过如下类比: Mutex是一把钥匙,一个人拿了就可进 ...

  4. 信号量 Semaphore

    一.简介         信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用,负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. Semaphore可以控制某个资源可被同时 ...

  5. windows核心编程-信号量(semaphore)

    线程同步的方式主要有:临界区.互斥区.事件.信号量四种方式. 前边讲过了互斥器线程同步-----windows核心编程-互斥器(Mutexes),这章我来介绍一下信号量(semaphore)线程同步. ...

  6. 秒杀多线程第八篇 经典线程同步 信号量Semaphore

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <且不超过最大资源数量. 第三个參数能够用来传出先前的资源计数,设为NULL表示不须要传出. 注意:当 ...

  7. 转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)

    载请注明出处:http://blog.csdn.net/ns_code/article/details/17524153 在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作 ...

  8. 多线程面试题系列(8):经典线程同步 信号量Semaphore

    前面介绍了关键段CS.事件Event.互斥量Mutex在经典线程同步问题中的使用.本篇介绍用信号量Semaphore来解决这个问题. 首先也来看看如何使用信号量,信号量Semaphore常用有三个函数 ...

  9. java笔记--对信号量Semaphore的理解与运用

    java Semaphore 信号量的使用: 在java中,提供了信号量Semaphore的支持. Semaphore类是一个计数信号量,必须由获取它的线程释放, 通常用于限制可以访问某些资源(物理或 ...

  10. 对信号量Semaphore的理解与运用

    转: java笔记--对信号量Semaphore的理解与运用 java Semaphore 信号量的使用: 在java中,提供了信号量Semaphore的支持. Semaphore类是一个计数信号量, ...

随机推荐

  1. python---django中自带分页类使用

    请先看在学习tornado时,写的自定义分页类:思路一致: python---自定义分页类 1.基础使用: 后台数据获取: from django.core.paginator import Pagi ...

  2. Spark记录-Scala数组/List/Map/Set

    import Array._ import scala.collection.mutable.Set object DataStructure { def main(args:Array[String ...

  3. HDU 5528 反演

    $f(m)=\sum\limits_{i=1}^{m-1}\sum\limits_{j=1}^{m-1}[(ij,m) \ne m]$,$g(n)=\sum\limits_{m|n}f(m)$,$1 ...

  4. prefab内容分析

    写在前面: 当前使用的unity版本:5.3.7p4. 如果打开prefab文件是乱码: 把editer的asset Srialization改为Force Text即可. 一.什么是Prefab P ...

  5. js简单的面试题

    1,js有哪些数据类型,数据类型的判断函数? String,Number,Boolean,Null,Undefined,Object 判断函数有:typeof,instanceof,construct ...

  6. [python]python三元表达式另类实现方式

    () variable = a if exper else b ()variable = (exper and [b] or [c])[] () variable = exper and b or c

  7. py-faster-rcnn代码阅读3-roidb.py

    roidb是比较复杂的数据结构,存放了数据集的roi信息.原始的roidb来自数据集,在trian.py的get_training_roidb(imdb)函数进行了水平翻转扩充数量,然后prepare ...

  8. Coins in a Line I & II

    Coins in a Line I There are n coins in a line. Two players take turns to take one or two coins from ...

  9. Linux进程托管与守护进程设置

    引言 在上一篇<Linux启动之旅>中,我们了解了Linux启动过程,在该过程的最后一步,init进程拉起/etc/init.d/rcN.d/目录下指定的守护进程(daemon).假若自定 ...

  10. linux下常用FTP命令 上传下载文件【转】

    1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密码 ...