先看一下stackoverflow上是怎么说的吧

原文地址:http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-difference

Semaphore can be counted, while mutex can only count to 1.

  Suppose you have a thread running which accepts client connections. This thread can handle 10 clients simultaneously. Then each new client sets the semaphore until it reaches 10.
When the Semaphore has 10 flags, then your thread won't accept new connections   Mutex are usually used for guarding stuff. Suppose your 10 clients can access multiple parts of the system. Then you can protect a part of the system with a mutex so when 1 client is connected to that sub-system,
no one else should have access. You can use a Semaphore for this purpose too. A mutex is a "Mutual Exclusion Semaphore".

简单的说 就是Mutex是排它的,只有一个可以获取到资源, Semaphore也具有排它性,但可以定义多个可以获取的资源的对象。

1.Semaphore

Semaphore维护了一组许可令牌,使用acquire方法去获取许可令牌,而使用release方法去释放一个令牌。实际上没有真正的使用许可令牌,Semaphore仅仅维护了可用的计数器而已。

Semaphore通常用来限制可用访问一些(物理或者逻辑)资源的访问线程数。例如,下面的类使用Semaphore来控制对pool内item的访问量。

示例:

class Pool {
private static final int MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
} public void putItem(Object x) {
if (markAsUnused(x))
available.release();
} // Not a particularly efficient data structure; just for demo protected Object[] items = ... whatever kinds of items being managed
protected boolean[] used = new boolean[MAX_AVAILABLE]; protected synchronized Object getNextAvailableItem() {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (!used[i]) {
used[i] = true;
return items[i];
}
}
return null; // not reached
} protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
} else
return false;
}
}
return false;
} }

在访问池内的item时,每个线程必须从Semaphore来获取一个许可令牌,保证必须有一个item是可用的。当线程使用完item后,将item还回到pool中,此时访问令牌返回给Semaphore。

注意:当调用acquire方法是没有保持一个同步锁,因为同步锁会阻碍item被释放给pool。Semaphore封装了需要的同步操作来保证对pool的访问进行限制,而不是为了维持pool本身的一致性来加入同步操作。

Semaphore默认设置为1,用来保证至少有一个许可令牌可用,此时可用看做一个mutext排它锁。mutex因作为二分Semaphore而出名,要么有一个许可令牌,要么没有许可令牌。当这样使用时,二分Semaphore有熟悉(不像大部分lock的实现那样),lock由线程释放而非owner(Semaphore没有ownership的概念)。这在某些特殊的场景下很有用,比如死锁的恢复。

Semaphore类的构造方法可以接受一个fairness参数,当这个参数设置为false时,此类不保证线程获取到许可令牌的顺序,特别是当运行抢夺资源时,意味着一个线程使用acquire获取许可令牌的时间可能会比一个等待队列在它之前的线程获取到令牌更早--逻辑上来说,新线程放置月等待队列的头部。当fairness参数设置为true时,Semaphore保证线程调用acquire方法时的顺序获取到令牌(即先进先出FIFO)

参考文献:

【1】http://www.cnblogs.com/think-in-java/p/5520462.html

【2】http://blog.csdn.net/sunp823/article/details/49886051

【3】http://coolxing.iteye.com/blog/1236909

java开发中的Mutex vs Semaphore的更多相关文章

  1. paip.java 开发中web server的选择jboss resin tomcat比较..

    paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax  艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...

  2. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  3. Java开发中文件读取方式总结

    JAVA开发中,免不了要读文件操作,读取文件,首先就需要获取文件的路径. 路径分为绝对路径和相对路径. 在文件系统中,绝对路径都是以盘符开始的,例如C:\abc\1.txt. 什么是相对路径呢?相对路 ...

  4. java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...

  5. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  6. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  7. 完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络]

    完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络] 地址:http://blog.csdn.net/qq_35101189/article/details/53729720?ref=m ...

  8. Java 开发中的对象拷贝

    前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...

  9. [ 转载 ] Java开发中的23种设计模式详解(转)

    Java开发中的23种设计模式详解(转)   设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...

随机推荐

  1. 对MBProgressHUD第三方进行源码分析

    GitHub源码地址,及时更新:iOS-Source-Code-Analyze MBProgressHUD是一个为iOS app添加透明浮层 HUD 的第三方框架.作为一个 UI 层面的框架,它的实现 ...

  2. Material Design之视图状态改变

    视图状态改变是通过StateListAnimator动画集来改变View的状态的,它可以使View在不同状态下发生不同的变化,如下是在drawable目录下定义一个StateListAnimator: ...

  3. SpriteBuilder中关于大量CCB文件的数字命名建议

    开发者总是频繁的填充文件名字使用额外的0,以此来对抗长久以来的长痘:数字排序.如果你觉得在数字名字前添加额外的0是一个好主意,比如说Level0001,因为可能你会创建数以千记的关卡--请不要这样做! ...

  4. Struts2技术内幕 读书笔记三 表示层的困惑

    表示层能有什么疑惑?很简单,我们暂时忘记所有的框架,就写一个注册的servlet来看看. index.jsp <form id="form1" name="form ...

  5. 实战项目开发细节:C语言分离一个16进制数取出相应的位1或0

    最近在公司开发一个关于钢琴的PCBA项目,项目大概是这样的,完成各种功能的测试,准备去工厂量产的时候可以通过软件快速甄别硬件是否短路,断路等问题. 其中,甄别好坏的方法是通过比如按键,或者其它的操作然 ...

  6. mybatis源码之SimpleStatementHandler

    /** * @author Clinton Begin */ public class SimpleStatementHandler extends BaseStatementHandler { pu ...

  7. HBase行锁

    1 行锁简介 在事务特性方面,hbase只支持单row的事务,不能保证跨row(cross-row)的事务.hbase通过行锁来实现单row事务.客户端进行操作时,可以显式对某一个行加锁,但是大部分情 ...

  8. objective-c 2.0的字面量Literals

    obj-c 2.0增加了许多核心对象字面量的简单语法,向ruby学习吗? 直接上代码: #import <Foundation/Foundation.h> int main(void){ ...

  9. html5中的网页结构

    一.html5中的大纲 在html5中,使用各种结构元素所描述出来的整个网页的层次结构,就是该网页的大纲.因此在组织这份大纲的时候,不能使用div元素,因为div元素只能当做容器,用在需要对网页中某个 ...

  10. 合法的json数组字符串,转换json

    List list = JSON.parseArray("[{'id':1,'name':'a'},{'id':2,'name','b'}]", JSONObject.class) ...