Semaphore,从字面意义上我们知道他是信号量的意思。在java中,一个计数信号量维护了一个许可集。Semaphore 只对可用许可的号码进行计数,并采取相应的行动。拿到信号量的线程可以进入代码,否则就等待。通过acquire()和release()获取和释放访问许可。

信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个“共享锁”。

Java并发提供了两种加锁模式:共享锁和独占锁。前面介绍的ReentrantLock就是独占锁。对于独占锁而言,它每次只能有一个线程持有,而共享锁则不同,它允许多个线程并行持有锁,并发访问共享资源。

独占锁它所采用的是一种悲观的加锁策略, 对于写而言为了避免冲突独占是必须的,但是对于读就没有必要了,因为它不会影响数据的一致性。如果某个只读线程获取独占锁,则其他读线程都只能等待了,这种情况下就限制了不必要的并发性,降低了吞吐量。而共享锁则不同,它放宽了加锁的条件,采用了乐观锁机制,它是允许多个读线程同时访问同一个共享资源的。

举一个生活中的例子,有一条单行道路口有一红绿灯在正常的绿灯时间内如果骑车速度都很平均只能过去20辆车,这就意味着排在前面的20辆肯定能过去红绿灯,后面的就只能等下一个绿灯了。但是如果这个时候有车不想过去这个路口它驶向了边上别的路,那么后面的车就有机会。下面我们来看一个简单的例子:

public class TestSemaphore {
public static void main(String[] args) {
final Semaphore semaphore = new Semaphore(5);
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i = 0;i<10;i++){
int j = 0;
executorService.submit(new A("car"+(j++),semaphore),"Thread"+(j++));
//new Thread(new A("car"+(j++),semaphore),"Thread"+(j++)).start();
if(i == 5){
try {
Thread.sleep(1000);
System.out.println("最后还有"+semaphore.availablePermits()+"个许可可用");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} System.out.println("最后还有"+semaphore.availablePermits()+"个许可可用");
} }
class A implements Runnable{
String carName;
private Semaphore semaphore; public A(String carName, Semaphore semaphore){
this.carName = carName;
this.semaphore = semaphore;
} public void getWay(){
System.out.println("this car is get the way" + Thread.currentThread().getName());
} public void run() {
try {
if(semaphore.availablePermits() > 0){
semaphore.acquire();
getWay();
semaphore.release();
}else{
System.out.println("请等待========");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

java并发编程(六)----(JUC)Semaphore的更多相关文章

  1. 【Java并发编程六】线程池

    一.概述 在执行并发任务时,我们可以把任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程,只要池里有空闲的线程,任务就会分配一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blo ...

  2. Java并发编程 (六) 线程安全策略

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.不可变对象-1 有一种安全的发布对象,即不可变对象. 1.不可变对象需要满足的条件 ① 对象创建以后 ...

  3. Java并发编程笔记之Semaphore信号量源码分析

    JUC 中 Semaphore 的使用与原理分析,Semaphore 也是 Java 中的一个同步器,与 CountDownLatch 和 CycleBarrier 不同在于它内部的计数器是递增的,那 ...

  4. Java并发编程(3) JUC中的锁

    一 前言 前面已经说到JUC中的锁主要是基于AQS实现,而AQS(AQS的内部结构 .AQS的设计与实现)在前面已经简单介绍过了.今天记录下JUC包下的锁是怎么基于AQS上实现的 二 同步锁 同步锁不 ...

  5. [java并发编程]基于信号量semaphore实现限流器

    目录 一.什么是信号量 二.信号量类Semaphore 三.实现限流器 欢迎关注我的博客,更多精品知识合集 一.什么是信号量 "信号量"在编程术语中使用单词semaphore,那什 ...

  6. Java并发编程系列之Semaphore详解

    简单介绍 我们以饭店为例,假设饭店只有三个座位,一开始三个座位都是空的.这时如果同时来了三个客人,服务员人允许他们进去用餐,然后对外说暂无座位.后来的客人必须在门口等待,直到有客人离开.这时,如果有一 ...

  7. 【Java并发编程实战】-----“J.U.C”:Semaphore

    信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...

  8. java并发编程笔记(六)——AQS

    java并发编程笔记(六)--AQS 使用了Node实现FIFO(first in first out)队列,可以用于构建锁或者其他同步装置的基础框架 利用了一个int类型表示状态 使用方法是继承 子 ...

  9. Java并发编程基础三板斧之Semaphore

    引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...

  10. Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo

    Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...

随机推荐

  1. Oracle数据库----查询

    --笛卡尔集select empno,ename, 员工表.deptno, 部门表.deptno, dname from 部门表, 员工表; --添加合适的条件,可以避免笛卡尔集,从而得到正确的多表查 ...

  2. linux修改时间显示格式

    1. 问题描述 Linux下经常使用 "ls - ll"命令查看文件夹或文件创建及权限信息,但是满屏的Mar .May.Jul有点小难受. 2. 解决方案 修改bash_profi ...

  3. windows登陆suse虚拟机

    vmware我还是比较偏向7.1.4版本,其他版本装在win7上似乎有点问题. windows平台下,使用vmware + opensuse的网络配置过程如下: 装完vm后,会在本地连接新创建两个新连 ...

  4. ItemsControl绑定的数据模板显示不同样式:模板选择器

    总所周知,wpf提供了数据模板,列表控件可以绑定数据实现批量显示同类型数据.不过同个数据模板显示不同的样式怎么办?这时我们可以用模板选择器. 首先我们可以将数据绑定到首先定义资源样式 <Data ...

  5. TensorFlow高效读取数据的方法——TFRecord的学习

    关于TensorFlow读取数据,官网给出了三种方法: 供给数据(Feeding):在TensorFlow程序运行的每一步,让python代码来供给数据. 从文件读取数据:在TensorFlow图的起 ...

  6. Y服务-你真的懂 Yaml 吗

    目录 一.什么是 Yaml 二.Yaml 的语法 三.操作 Yaml A. 引入框架 B. 代码片段 C. 完整案例 参考文档 在Java 的世界里,配置的事情都交给了 Properties,要追溯起 ...

  7. C语言入门4-运算符和表达式

    一.     分类 C语言一共有34种运算符,10种运算类型,本节我们要掌握的有( 7 种) 算术运算符(+.-.*./.%). 关系运算符(>.>=.==.!=.<.<=). ...

  8. Java中注释的使用

    Java 中注释有三种类型:单行注释.多行注释.文档注释 我们可以通过 javadoc 命令从文档注释(/**aa*/)中提取内容,生成程序的 API 帮助文档. 打开首页,查看下生成的 API 文档 ...

  9. 数据库---T-SQL语句:查询语句(二)

    >查询: 一.查询所有数据: select * from Info    ---查询所有数据(行) select Name from Info  ---查询特定列(Name列) select N ...

  10. python面向对象-封装-property-接口-抽象-鸭子类型-03

    封装 什么是封装: # 将复杂的丑陋的隐私的细节隐藏到内部,对外提供简单的使用接口 或 # 对外隐藏内部实现细节,并提供访问的接口 为什么需要封装 1.为了保证关键数据的安全性 2.对外部隐藏内部的实 ...