Semaphore:动态增减信号量,用于控制对某资源访问的同一时间的并发量。类似于令牌,谁拿到令牌(acquire)就可以去执行了,如果没有令牌则需要等待。

【如何获取】:
semaphore.tryAcquire(),尝试获取,不阻塞。

semaphore.acquire(),没信号量可用时,将进行阻塞等,可以被中断。

acquireUninterruptibly():获取信号量,将进行阻塞,但会忽略线程的中断而且不会抛出任何异常。

【如何释放】:
semaphore.release();
线程抛出各种异常,都别忘了在finally中释放信号量;
如果释放的比获取的信号量还多,例如获取了2个,释放了5次,那么当前信号量就动态的增加为5了,要注意。如下图所示:

例子:用信号量semaphore实现生产者与消费者

请仔细体会里面关于仓库的处理,

1 是如何保证入库时,如果仓库满就等待,

2 出库时,如果仓库无货就等待的。

3 以及对仓库只有10个库位的处理。

4 对同步问题的处理。

public class TestSemaphore {
public static void main(String[] args) {
for (int i = 0; i <= 3; i++) {
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
}
}
//仓库
static WareHouse buffer = new WareHouse();
//生产者
static class Producer implements Runnable{
static int num = 1;
public void run() {
int n = num++;
while(true){
try{
buffer.put(n);
System.out.println(">"+n);
Thread.sleep(10);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer implements Runnable{
public void run() {
while (true) {
try {
System.out.println("<"+buffer.take());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class WareHouse{
//非满锁
final Semaphore notFull = new Semaphore(10);
//非空锁
final Semaphore notEmpty = new Semaphore(0);
//互斥锁
final Semaphore mutex = new Semaphore(1);
//库存容量
final Object[] items = new Object[10];
int putPosi, takePosi, count;
public void put(Object x)throws InterruptedException{
try{
notFull.acquire();
mutex.acquire();
items[putPosi] = x;
if (++putPosi == items.length) {
putPosi = 0;
}
count++;
}finally{
notEmpty.release();
mutex.release();
}
}
public Object take()throws InterruptedException{
notEmpty.acquire();
mutex.acquire();
try{
Object x = items[takePosi];
if(++takePosi == items.length){
takePosi = 0;
}
--count;
return x;
}finally{
notFull.release();
mutex.release();
}
}
}
}

也可以把Semaphore当锁来使用

当信号量的数量上限是1时,Semaphore可以被当做锁来使用。通过take和release方法来保护关键区域。请看下面的例子:

BoundedSemaphore semaphore = new BoundedSemaphore(1);
...
semaphore.acquire();
try{
//critical section
} finally {
semaphore.release();
}

JAVA多线程之Semaphore的更多相关文章

  1. Java多线程之Semaphore信号量

      转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6557874.html  学过操作系统的对 信号量 这个词应该不陌生,它是用来进行进程间通信,控制对 临界区 ...

  2. Java多线程之ConcurrentSkipListMap深入分析(转)

    Java多线程之ConcurrentSkipListMap深入分析   一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...

  3. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  4. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

  5. java多线程之yield,join,wait,sleep的区别

    Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...

  6. Java多线程之Runnable与Thread

    Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...

  7. JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止

    JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止 背景 当单线程的程序发生一个未捕获的异常时我们可以采用try....catch进行异常的捕获,但是在多线程环境 ...

  8. java多线程之wait和notify协作,生产者和消费者

    这篇直接贴代码了 package cn.javaBase.study_thread1; class Source { public static int num = 0; //假设这是馒头的数量 } ...

  9. Java——多线程之Lock锁

    Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...

随机推荐

  1. DNS Doctoring

    NAT的应用可以让路由器在不同地址域内路由数据包.一个暴露在外的应用服务器,通常同时拥有了内网和外网的IP地址.这在DNS解析时可能带来麻烦. 根据DNS服务器的部署位置和配置,对同一内网中的应用服务 ...

  2. MyEclipse 手动安装Velocity 编辑器

    最近项目有使用Velocity 模板引擎,从而会用到*.VM页面!Myeclipse打开VM页面字体一片漆黑,哪有JSP那样看起来舒服(个人感觉)!为了解决这一问题就要安装Velocity编辑器,安装 ...

  3. python并发编程之多进程1互斥锁与进程间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  4. numpy和matlab计算协方差矩阵的不同(matlab是标准的,numpy相当于转置后计算)

    matlab是标准的,numpy相当于转置后计算 >> x = [2,0,-1.4;2.2,0.2,-1.5;2.4,0.1,-1;1.9,0,-1.2] x = 2.0000    0 ...

  5. TCP/IP四层体系结构

    1.数据链路层  2.网络层  3.传输层  4.应用层 , 其中IP是在第二层网络层中,TCP是在第3层传输层中, Internet体系结构最重要的是TCP/IP协议,是实现互联网络连接性和互操作性 ...

  6. JSP有哪些动作?

    JSP使用动作来动态的插入文件,实现重定向和对JavaBean的引用等功能.它公有6个基本动作:jsp:include,jsp:useBean,jsp:setProperty,jsp:getPrope ...

  7. swiper实现左右滑动图片

    ref:http://www.swiper.com.cn/usage/index.html help:https://segmentfault.com/a/1190000002962202 src: ...

  8. 为什么ps中CPU占用率会有超出%100的现象?

    前面的关于ps中的%CPU的含义一文已经介绍了CPU占用率的含义,那么为什么有时会在ps的输出中看到CPU占用率超出%100的现象呢?我们知道在/proc目录下每个进程都会有一个以它的PID以名字的目 ...

  9. HN669打包工具--调试文档

    调试有两种方式,一是直接在游戏工程上面调试,这比较麻烦,需要根据插件配置文件和脚本文件去配置好工程选项后,才能调试.简单一点就是通过脚本文件打包后会有生成游戏工程对应每个渠道的工程. 如下图:这个工程 ...

  10. ASP.NET MVC 小牛之旅1:何谓MVC

    在学习ASP.NET MVC之前首先了解什么 是MVC ? MVC不是一种语言,严格来说也不算一个技术,而是开发时所使用的一种架构(框架),它就像是一种开发观念,或是一个设计样式. MVC让软件开发的 ...