Semaphore 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
一個計數信號旗。
[Android.Runtime.Register("java/util/concurrent/Semaphore", DoNotGenerateAcw=true)]
public class Semaphore : Java.Lang.Object, IDisposable, Java.IO.ISerializable
[<Android.Runtime.Register("java/util/concurrent/Semaphore", DoNotGenerateAcw=true)>]
type Semaphore = class
inherit Object
interface ISerializable
interface IJavaObject
interface IDisposable
interface IJavaPeerable
- 繼承
- 屬性
- 實作
備註
一個計數信號旗。 概念上,信號量維持一套許可證。 每家公司 #acquire 若有需要會封鎖,直到有許可證,然後再申請。 每項都 #release 增加了許可證,可能釋放阻擋收購方。 然而,實際上並未使用任何許可證物件; Semaphore Just 會記錄可用數量並依此行事。
信號量常用於限制可存取某些(物理或邏輯)資源的執行緒數量。 舉例來說,這裡有一個類別使用信號量來控制對一組物品的存取:
{@code
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;
}
}}
在取得物品前,每個線索必須取得信號旗的許可,以確保該物品可供使用。 當執行緒完成該項目後,會返回池中,並返回授權給信號板,讓另一個執行緒取得該項目。 請注意,當呼叫時不會保留 #acquire 同步鎖,因為那樣會阻止項目被返回池中。 信號量封裝了限制存取池所需的同步,與維持池本身一致性所需的同步是分開的。
初始化為1且最多只有一張許可證的臂板,可以作為互斥鎖。 這通常被稱為 <電磁>二元信號量</em>,因為它只有兩種狀態:一種許可可用,或零許可。 當以這種方式使用時,二元信號量具有(與許多 java.util.concurrent.locks.Lock 實作不同的)特性,即 ”鎖”可由非擁有者執行緒釋放(因為臂量不存在所有權概念)。 這在某些特殊情境下非常有用,例如死鎖恢復。
此類別的構造子可選擇接受 <em>公平<性/em> 參數。 當設為 false 時,此類別不保證執行緒取得許可的順序。 特別是,<>em barging</em> 是被允許的,也就是說,呼叫執行#acquire緒可以在等待的執行緒之前被分配一個許可——邏輯上新執行緒會將自己置於等待執行緒佇列的首位。 當公平性設定為真時,信號量保證呼叫任一方法的執行緒 #acquire() acquire 會依照其呼叫順序(先入先出)獲得許可。FIFO)。 請注意,先出排序必然適用於這些方法中特定的內部執行點。 因此,一個執行緒可能先於另一個執行緒呼叫 acquire ,但在另一個執行緒之後才抵達排序點,亦同理,當從方法返回時也是如此。 另外請注意,無時限 #tryAcquire() tryAcquire 方法不尊重公平設定,但會接受所有可用的許可證。
一般來說,用於控制資源存取的信號量應初始化為公平,以確保不會有執行緒被剝奪資源存取。 在使用旗量進行其他類型的同步控制時,非公平排序的吞吐量優勢往往超過公平性考量。
此類別同時提供多項許可證的便利方法#acquire(int) acquire#release(int) release。 這些方法通常比迴圈更有效率且有效。 然而,他們並未建立任何優先順序。 例如,若執行緒 A 呼叫 s.acquire(3,執行緒 B 呼叫 s.acquire(2),且兩個許可可用,則無法保證執行緒 B 會取得,除非其取得先行且 Semaphore s 處於公平模式。
記憶體一致性效應:在呼叫「釋放」方法(如 release()<i>happen-before</i> 動作)之前,執行緒中在成功「取得」方法 acquire() (如另一執行緒)之前的動作。
已在1.5中新增。
Java 文件 java.util.concurrent.Semaphore。
本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。
建構函式
| 名稱 | Description |
|---|---|
| Semaphore(Int32, Boolean) |
以指定許可數量和公平度設定創建 a |
| Semaphore(Int32) |
建立 |
| Semaphore(IntPtr, JniHandleOwnership) |
建立 JNI 物件的 Managed 表示法時使用的建構函式;由運行時間呼叫。 |
屬性
| 名稱 | Description |
|---|---|
| Class |
傳回這個 |
| Handle |
基礎Android實例的句柄。 (繼承來源 Object) |
| HasQueuedThreads |
查詢是否有執行緒正在等待接收。 |
| IsFair |
如果此臂板的公平性設定為真,則可回退 |
| JniIdentityHashCode |
取得由互通執行時指派給此 Java 對等端的身份雜湊碼。 (繼承來源 Object) |
| JniManagedPeerState |
一個計數信號旗。 (繼承來源 JavaObject) |
| JniPeerMembers |
一個計數信號旗。 |
| PeerReference |
取得這個 Java 節點的 JNI 物件參考。 (繼承來源 Object) |
| QueuedThreads |
回傳包含可能等待取得的執行緒的集合。 |
| QueueLength |
回傳等待獲取執行緒數量的估計值。 |
| ThresholdClass |
此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。 |
| ThresholdType |
此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。 |
方法
| 名稱 | Description |
|---|---|
| Acquire() |
從此信號量取得許可,阻塞直到有許可可用,或執行緒被 Thread#interrupt 中斷。 |
| Acquire(Int32) |
從此信號量取得指定數量的許可,阻塞直到所有可用或執行緒被 Thread#interrupt 中斷。 |
| AcquireUninterruptibly() |
從該信號旗取得許可證,封鎖直到有許可證。 |
| AcquireUninterruptibly(Int32) |
從此信號旗取得指定數量的許可證,封鎖直到所有許可證都可用。 |
| AvailablePermits() |
此臂板中回傳目前可用的許可證數量。 |
| Clone() |
建立並傳回這個 對象的複本。 (繼承來源 Object) |
| Construct(JniObjectReference, JniObjectReferenceOptions) |
一個計數信號旗。 (繼承來源 JavaObject) |
| Dispose() |
釋放該 Java 節點所持有的資源。 (繼承來源 Object) |
| Dispose(Boolean) |
釋放該 Java 節點所持有的資源。 (繼承來源 Object) |
| DisposeUnlessReferenced() |
一個計數信號旗。 (繼承來源 JavaObject) |
| DrainPermits() |
取得並歸還所有立即可用的許可證,若有負面許可證則予以釋放。 |
| Equals(Object) |
一個計數信號旗。 (繼承來源 JavaObject) |
| Equals(Object) |
指出其他物件是否「等於」這個物件。 (繼承來源 Object) |
| GetHashCode() |
傳回此物件的雜湊碼值。 (繼承來源 Object) |
| JavaFinalize() |
已淘汰.
當垃圾收集決定不再參考物件時,垃圾收集行程在 物件上呼叫。 (繼承來源 Object) |
| Notify() |
喚醒正在等候此物件監視器的單一線程。 (繼承來源 Object) |
| NotifyAll() |
喚醒正在等候此物件監視器的所有線程。 (繼承來源 Object) |
| ReducePermits(Int32) |
可依標示的減少減少可用許可證數量。 |
| Release() |
釋放許可證,並將其交還給信號旗。 |
| Release(Int32) |
釋放指定數量的許可證,並將其退還給信號板。 |
| SetHandle(IntPtr, JniHandleOwnership) |
設定 Handle 屬性。 (繼承來源 Object) |
| SetPeerReference(JniObjectReference, JniObjectReferenceOptions) |
一個計數信號旗。 (繼承來源 JavaObject) |
| ToArray<T>() |
從這個 Java 陣列包裝器建立一個受管理陣列。 (繼承來源 Object) |
| ToString() |
傳回物件的字串表示。 (繼承來源 Object) |
| TryAcquire() |
只有在召喚時有許可證時,才會從此信號旗取得許可。 |
| TryAcquire(Int32, Int64, TimeUnit) |
若所有許可在等待時間內全部可用且目前執行緒未被 Thread#interrupt 中斷,則從此信號量取得指定數量的許可。 |
| TryAcquire(Int32) |
只有在召喚時所有許可證均已可用時,才會從此信號量取得指定數量的許可證。 |
| TryAcquire(Int64, TimeUnit) |
若在指定等待時間內有該信號量可用且目前執行緒未被 Thread#interrupt 中斷,則會從此信號量取得許可。 |
| UnregisterFromRuntime() |
將此 Java 節點從互通執行時中取消註冊。 (繼承來源 Object) |
| Wait() |
讓目前線程等候直到喚醒為止,通常是藉由em <notified/em>或<em>interrupted</em> 來喚醒它。<> (繼承來源 Object) |
| Wait(Int64, Int32) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
| Wait(Int64) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
明確介面實作
| 名稱 | Description |
|---|---|
| IJavaPeerable.Disposed() |
一個計數信號旗。 (繼承來源 JavaObject) |
| IJavaPeerable.Finalized() |
一個計數信號旗。 (繼承來源 JavaObject) |
| IJavaPeerable.JniObjectReferenceControlBlock |
一個計數信號旗。 (繼承來源 JavaObject) |
| IJavaPeerable.SetJniIdentityHashCode(Int32) |
一個計數信號旗。 (繼承來源 JavaObject) |
| IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
一個計數信號旗。 (繼承來源 JavaObject) |
| IJavaPeerable.SetPeerReference(JniObjectReference) |
一個計數信號旗。 (繼承來源 JavaObject) |
| IJavaPeerable.UnregisterFromRuntime() |
一個計數信號旗。 |
擴充方法
| 名稱 | Description |
|---|---|
| GetJniTypeName(IJavaPeerable) |
取得實例 |
| JavaAs<TResult>(IJavaPeerable) |
試著強制 |
| JavaCast<TResult>(IJavaObject) |
執行 Android 執行時間檢查的類型轉換。 |
| JavaCast<TResult>(IJavaObject) |
一個計數信號旗。 |
| TryJavaCast<TResult>(IJavaPeerable, TResult) |
試著強制 |