一、概念

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. Spark记录-Scala类与对象小例子

    //基类-Person class Person(val na: String, val ag: Int) { //属性 var name: String = na var age: Int = ag ...

  2. Spring MVC 中 @ModelAttribute 注解的妙用

    Spring MVC 中 @ModelAttribute 注解的妙用 Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发.其中 @Controller 和 @Rest ...

  3. bzoj千题计划190:bzoj4300: 绝世好题

    http://www.lydsy.com/JudgeOnline/problem.php?id=4300 f[i] 表示第i位&为1的最长长度 #include<cstdio> # ...

  4. ASP.NET保存信息总结(Application、Session、Cookie、ViewState和Cache等)

    以下是关于ASP.NET中保存各种信息的对象的比较,理解这些对象的原理,对制作完善的程序来说是相当有必要的(摘至互联网,并非原创--xukunping) 在ASP.NET中,有很多种保存信息的对象.例 ...

  5. CodeAction_beta02 斐波那契 (多维DP)

    题面: solution: 这题和斐波那契数列没有任何关系!!!!! 这题就是一个无脑DP!!!!!!!!!! 因为所有数都要出现至少一次,所以只需考虑其组合而不用考虑其排列,最后乘个 n!就是了(意 ...

  6. lemon spj无效编译器解决方法

    反正我是被坑了很久,心里增的敲难过呀! 我曾经无数次的想把它解决掉: 啊啊啊啊啊啊! 什么嘛!什么嘛! 这个空白的框框里到底要填什么嘛!!! 你已经是一个成熟的lemon了,就不能自动识别给个选项吗! ...

  7. 原生JS获取元素的位置与尺寸

    1.内高度.内宽度: 内边距 + 内容框 element.clientWidth element.clientHeight 2.外高度,外宽度: 边框 + 内边距 + 内容框 element.offs ...

  8. 为什么mysqlbinlog --database选项不起作用

    群里看到有同学提问,多瞅了眼 [root@mysql55 mysql]# mysqlbinlog --no-defaults -vv --base64-output=decode-rows mysql ...

  9. 查询总结、HQL语法、QBC(QueryByCriteria)深入学习

    1.查询总结 在之前的批量查询练习的时候练习基本五种查询方法的使用: 1.OID查询---根据对象ID进行查询 2.对象属性导航查询: obj.getXXX 3.HQL查询:Query对象查询 4.Q ...

  10. Hibernate 二级缓存疑难点

    一级缓存:缓存实体 二级缓存:缓存实体 Hibernate查询缓存缓存的是查询出来的实体的部分属性结果集和实体的ID(注意这里不是实体). Hibernate查询缓存:对List起作用.但是Hiber ...