1、Semaphore概念

Semaphore是Java1.5之后提供的一种同步工具,Semaphore可以维护访问自身线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而release() 释放一个许可。

Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以去占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合,所以单个信号量的Semaphore对象的功能就和synchronized实现互斥是共同的

2、功能扩展

1、Semaphore往往结合线程池使用,比如建立一个固定大小为10的线程池,最多线程并发数为10个,当你提交20个任务到线程池的时候,线程池会安排这10个线程优先接待20个任务中的10个,当优先安排的10个中有完成的会去接待剩下的10个任务中的某一个任务,直到执行完所有任务为止。但是如果此时引入了Semaphore对象,所传的值是5的时候,那么这线程池中10个线程只有5个能够并发执行,此时就做到了限量访问的作用。
 
2、当Semaphore构造方法中传入的参数是1的时候,此时线程并发数最多是1个,即是线程安全的,这种方式也可以做到现场互斥。Java实现互斥线程同步有三种方式synchronized、lock 、单Semaphore

3、Semaphore的使用demo如下

  1.  
    public class SemahoreDemo {
  2.  
     
  3.  
    public static void main(String[] args) {
  4.  
    ExecutorService executorService = Executors.newCachedThreadPool();
  5.  
     
  6.  
    final Semaphore semaphore = new Semaphore(1,true);
  7.  
     
  8.  
    for(int i=0;i<10;i++){
  9.  
    Runnable runnable = new Runnable() {
  10.  
    @Override
  11.  
    public void run() {
  12.  
    try {
  13.  
    semaphore.acquire();
  14.  
    } catch (InterruptedException e) {
  15.  
    e.printStackTrace();
  16.  
    }
  17.  
     
  18.  
    System.err.println("线程"+Thread.currentThread().getName()+"进入,已有"+(3-semaphore.availablePermits())+"并发");
  19.  
     
  20.  
    try {
  21.  
    Thread.sleep((long)(Math.random()*1000));
  22.  
    } catch (InterruptedException e) {
  23.  
    e.printStackTrace();
  24.  
    }
  25.  
     
  26.  
    System.out.println("线程"+Thread.currentThread().getName()+"即将离开");
  27.  
     
  28.  
    semaphore.release();
  29.  
     
  30.  
    System.err.println("线程"+Thread.currentThread().getName()+"已经离开"+"当前并发数:"+(3-semaphore.availablePermits()));
  31.  
    }
  32.  
    };
  33.  
     
  34.  
    executorService.execute(runnable);
  35.  
    }
  36.  
     
  37.  
    executorService.shutdown();
  38.  
     
  39.  
    }
  40.  
     
  41.  
    }

java高级之信号灯Semaphore的更多相关文章

  1. java高级---->Thread之Semaphore的使用

    Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制.今天我们就学习一下Semaphore的用法. java中多线程Semaphore的使用 关于Semapho ...

  2. Java并发编程:Semaphore、CountDownLatch、CyclicBarrier

    首先我们来实现一个功能:当我们启动一个系统的时候需要初始化许多数据,这时候我们可能需要启动很多线程来进行数据的初始化,只有这些系统初始化结束之后才能够启动系统.其实在Java的类库中已经提供了Sema ...

  3. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  4. paip.java 架构师之路以及java高级技术

    paip.java 架构师之路以及java高级技术 1.    Annotation 设计模式... 概念满天飞.ORM,IOC,AOP. Validator lambda4j memcache. 对 ...

  5. paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  6. Java高级之线程同步

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于实现多线程的意义,"从业四年看并发"一文已经讲述,而本篇主要讲一下常用的设计 ...

  7. Java高级之类结构的认识

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! Java体系包括,各种版本的虚拟机,可执行文件,各种第三方类库,Java API类库,Java语言 ...

  8. Java高级软件工程师面试考纲(转)

    如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构.算法.网络.操作系统等知识.因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对 ...

  9. Java高级软件工程师面试考纲

    如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构.算法.网络.操作系统等知识.因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对 ...

随机推荐

  1. 九. 常用类库、向量与哈希1.Java基础类库

    Java 的类库是 Java 语言提供的已经实现的标准类的集合,是 Java 编程的 API(Application Program Interface),它可以帮助开发者方便.快捷地开发 Java ...

  2. Java StringBuffer与StringBuider

    String 的值是不可变的,每次对String的操作都会生成新的String对象,不仅效率低,而且耗费大量内存空间. StringBuffer类和String类一样,也用来表示字符串,但是Strin ...

  3. Java杂谈1——虚拟机内存管理与对象访问

    1.理解JAVA虚拟机的内存管理 运行时的数据区 从java虚拟机的内存分配来看,一个java程序运行时包含了如下几个数据区: a)     程序计数寄存器(Program Counter Regis ...

  4. P2P通信标准协议(三)之ICE

    在P2P通信标准协议(二)中,介绍了TURN的基本交互流程,在上篇结束部分也有说到,TURN作为STUN 协议的一个拓展,保持了STUN的工具性质,而不作为完整的NAT传输解决方案,只提供穿透NAT的 ...

  5. 关于iframe的高度自适应问题(js)

    function SetCwinHeight() { var cwin=document.getElementById("cwin"); if (document.getEleme ...

  6. Qt creator发布可执行文件方式----靠谱

    1.首先用 QtCreator 新建一个 Qt Widgets Application 项目,直接用默认的 QMainWindow 程序就可以了,项目名字假定是serial_port.exe. 然后以 ...

  7. remmina rdp远程连接windows

    一.remmina rdp远程连接windows sudo apt-get install remmina 二.ubuntu设置桌面快捷方式 ①找到Remmina远程桌面客户端 比如在[搜索您的本地和 ...

  8. ES里关于数组的拓展

    一.静态方法 在ES6以前,创建数组的方式主要有两种,一种是调用Array构造函数,另一种是用数组字面量语法,这两种方法均需列举数组中的元素,功能非常受限.如果想将一个类数组对象(具有数值型索引和le ...

  9. VirtualBox下Linux(centos)扩展磁盘空间

    最近在Linux里做文件合并,做分词,磁盘空间不够,把扩展磁盘空间方法记录一下. 1.在VirtualBox安装路径下(例如C:\Program Files\Oracle\VirtualBox> ...

  10. 【共享单车】—— React后台管理系统开发手记:UI菜单各个组件使用(Andt UI组件)

    前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...