先看一下stackoverflow上是怎麼說的吧html
原文地址:http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-differencejava
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也具備排它性,但能夠定義多個能夠獲取的資源的對象。ui
1.Semaphorethis
Semaphore維護了一組許可令牌,使用acquire方法去獲取許可令牌,而使用release方法去釋放一個令牌。實際上沒有真正的使用許可令牌,Semaphore僅僅維護了可用的計數器而已。spa
Semaphore一般用來限制可用訪問一些(物理或者邏輯)資源的訪問線程數。例如,下面的類使用Semaphore來控制對pool內item的訪問量。.net
示例:線程
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。code
注意:當調用acquire方法是沒有保持一個同步鎖,由於同步鎖會阻礙item被釋放給pool。Semaphore封裝了須要的同步操做來保證對pool的訪問進行限制,而不是爲了維持pool自己的一致性來加入同步操做。htm
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