java开发中的Mutex vs Semaphore
先看一下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
相关文章
- linux_java_启动一个项目脚本
- 从java开发转行做测试的心路历程
- 【JAVA】 Statement与ProparedStatement的区别(实例代码对比)
- Java项目(前端vue后台java微服务)在线考试系统(java+vue+springboot+mysql+maven)
- 【Java】java基本知识
- Java开发环境的搭建以及使用eclipse从头一步步创建java项目
- Garbage Collectors – Serial vs. Parallel vs. CMS vs. G1 (and what’s new in Java 8)
- Java IO流学习总结
- Java底层四个核心技术
- java中String数组和List的互相转化
- 如何选择一台适合Java开发的电脑
- elasticsearch之JAVA环境变量报错:could not find java; set JAVA_HOME or ensure java is in PATH
- 《大规模Java平台虚拟化与调优》—— 导读
- jsp头部报错:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- Java_解决java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
- java学习-AES加解密之AES-128-CBC算法
- 『Java练习生的自我修养』java-se进阶⁵ • 常用IO流
- Java实现 pdf 转 图片
- Java操作Mongodb 保存/读取java对象到/从mongodb
- 【JAVA】泛型——对数据类型转换和数据存取方法的逐步优化过程
- java学习路线-Java技术人员之路从0基础到高级
- java.lang.OutOfMemoryError: Java heap space错误及处理办法(收集整理、转)
- 构建高性能服务(三)Java高性能缓冲设计 vs Disruptor vs LinkedBlockingQueue--转载
- Java hutool/java 常用方法
- Java中利用keytool创建一个CA证书
- java比较字符串