所有已知實作類別:
AbstractQueuedLongSynchronizer.Condition,,,
Conditionwait、
notify 和
notifyAll)
分解成截然不同的對象,以便透過將這
些對象與任意Lock 實作組合使用多個物件,為每個物件提供多個物件( wait-set)。其中,Lock
取代了
synchronized 方法和語句的使用,Condition 取代了 Object 監視器方法的使用。
條件(也稱為
條件佇列 或
條件變數)為執行緒提供了一個含義,以便在某個狀態條件現在可能為true 的另一個執行緒通知它之前,一直掛起該執行緒(即讓其“等待”)。因為存取此共享狀態資訊發生在不同的執行緒中,所以它必須受保護,因此要將某種形式的鎖與該條件相關聯。等待提供一個條件的主要屬性是:
釋放相關的鎖,並掛起當前線程,就像 Object.wait 所做的那樣。 Condition 實例實質上被綁定到一個鎖上。若要為特定
實例取得 Condition
實例,請使用其 newCondition()
方法。 作為一個範例,假定有一個綁定的緩衝區,它支援
put
和 take 方法。如果試圖在空的緩衝區上執行
操作,則在某一個項目變得可用之前,執行緒將一直阻塞;如果試圖在滿的緩衝區上執行put
操作,則在有空間變得可用之前,線程將一直阻塞。我們喜歡在單獨的等待 set 中保存 put
線程和 take
線程,這樣就可以在緩衝區中的項或空間變得可用時利用最佳規劃,一次只通知一個線程。可以使用兩個 Condition
實例來做到這一點。 <pre class="brush:php;toolbar:false">public interface Condition</pre>
(ArrayBlockingQueue
類別提供了這個功能,因此沒有理由去實現這個範例類別。)
實作可以提供不同於Object
監視器方法的行為和語義,例如受保證的行為和語義,例如受保證的行為和語義,例如受注意排序,或在執行通知時不需要保持一個鎖。如果某個實作提供了這樣特殊的語義,則該實作必須記錄這些語義。
注意,Condition
實例只是一些普通的對象,它們本身可以用作 synchronized
語句中的目標,並且可以呼叫自己的
和 notification
監視器方法。取得 Condition
實例的監視器鎖定或使用其監視器方法,與取得和該 Condition
相關的 Lock
或使用其 waiting
和 signalling
方法沒有什麼特定的關係。為了避免混淆,建議除了在其自身的實作中之外,切勿以這種方式使用 Condition
實例。 除非另行說明,否則為任何參數傳遞
null
值將導致拋出 NullPointerException
。
實現注意事項在等待
Condition
時,允許發生“
應該總是在一個循環中被等待,並測試正被等待的狀態聲明。某個實作可以隨意移除可能的虛假喚醒,但建議應用程式程式設計師總是假定這些虛假喚醒可能發生,因此總是在一個循環中等待。 三種形式的條件等待(可中斷、不可中斷和超時)在一些平台上的實現以及它們的性能特徵可能會有所不同。尤其是它可能很難提供這些特性和維護特定語義,例如排序保證。更進一步地說,中斷線程實際掛起的能力在所有平台上並不是總是可行的。
因此,並不要求某個實現為所有三種形式的等待定義完全相同的保證或語義,也不要求其支援中斷執行緒的實際掛起。
要求實現清楚地記錄每個等待方法提供的語義和保證,在某個實作不支援中斷執行緒的掛起時,它必須遵從此介面中定義的中斷語意。 由於中斷通常意味著取消,而通常很少進行中斷檢查,因此實作可以先於普通方法的返回來回應中斷。即使出現在另一個操作後的中斷可能會釋放執行緒鎖定時也是如此。實現應記錄此行為。 從以下版本開始: 1.5 造成当前线程在接到信号或被中断之前一直处于等待状态。 与此 其他某个线程调用此 其他某个线程调用此 其他某个线程中断当前线程,且支持中断线程的挂起;或者 发生“虚假唤醒” 在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。 如果当前线程: 在进入此方法时已经设置了该线程的中断状态;或者 在支持等待和中断线程挂起时,线程被中断, 则抛出 实现注意事项 假定调用此方法时,当前线程保持了与此 与响应某个信号而返回的普通方法相比,实现可能更喜欢响应某个中断。在这种情况下,实现必须确保信号被重定向到另一个等待线程(如果有的话)。 抛出: 造成当前线程在接到信号之前一直处于等待状态。 与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下三种情况之一 以前,当前线程将一直处于休眠状态: 其他某个线程调用此 其他某个线程调用此 发生“虚假唤醒” 在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。 如果在进入此方法时设置了当前线程的中断状态,或者在等待时,线程被中断,那么在接到信号之前,它将继续等待。当最终从此方法返回时,仍然将设置其中断状态。 实现注意事项 假定调用此方法时,当前线程保持了与此 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。 与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下五种情况之一 以前,当前线程将一直处于休眠状态: 其他某个线程调用此 其他某个线程调用此 其他某个线程中断当前线程,且支持中断线程的挂起;或者 已超过指定的等待时间;或者 发生“虚假唤醒”。 在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。 如果当前线程: 在进入此方法时已经设置了该线程的中断状态;或者 在支持等待和中断线程挂起时,线程被中断, 则抛出 在返回时,该方法返回了所剩毫微秒数的一个估计值,以等待所提供的 设计注意事项:此方法需要一个 nanosecond 参数,以避免在报告剩余时间时出现截断错误。在发生重新等待时,这种精度损失使得程序员难以确保总的等待时间不少于指定等待时间。 实现注意事项 假定调用此方法时,当前线程保持了与此 与响应某个信号而返回的普通方法相比,或者与指示所使用的指定等待时间相比,实现可能更喜欢响应某个中断。在任意一种情况下,实现必须确保信号被重定向到另一个等待线程(如果有的话)。 参数: 返回: 抛出: 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。此方法在行为上等效于: 参数: 返回: 如果在从此方法返回前检测到等待时间超时,则返回 抛出: 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。 与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下五种情况之一 以前,当前线程将一直处于休眠状态: 其他某个线程调用此 其他某个线程调用此 其他某个线程中断当前线程,且支持中断线程的挂起;或者 指定的最后期限到了;或者 发生“虚假唤醒”。 在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。 如果当前线程: 在进入此方法时已经设置了该线程的中断状态;或者 在支持等待和中断线程挂起时,线程被中断, 则抛出 返回值指示是否到达最后期限,使用方式如下: 实现注意事项 假定调用此方法时,当前线程保持了与此 与响应某个信号而返回的普通方法相比,或者与指示是否到达指定最终期限相比,实现可能更喜欢响应某个中断。在任意一种情况下,实现必须确保信号被重定向到另一个等待线程(如果有的话)。 参数: 返回: 如果在返回时已经到达最后期限,则返回 抛出: 唤醒一个等待线程。 如果所有的线程都在等待此条件,则选择其中的一个唤醒。在从 唤醒所有等待线程。 如果所有的线程都在等待此条件,则唤醒所有线程。在从
void await<strong></strong>
( ) await
造成目前執行緒在接到訊號或中斷前一直處於等待狀態。
<strong></strong> boolean
(long time執行緒在接到訊號、中斷或到達指定等待時間前一直處於等待狀態。 (long nanosTimeout) long awaitNanos<strong></strong>
awaitNanos(long nanosTimeout) awaitNanos
(long nanosTimeout) 收到當前信號或到達指定等待時間前一直處於等待狀態。
void
<strong></strong>
awaitUninterruptibly 。
void boolean
<strong>awaitUntil</strong>(Date deadline) 接獲現有訊號中斷或到達指定最後期限前一直處於等待狀態。
signal()
<strong></strong>
void
signalAll
()
<strong></strong>
await
void await()
throws InterruptedException
Condition
相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一 以前,当前线程将一直处于休眠状态:
Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者Condition
的 signalAll()
方法;或者
InterruptedException
,并清除当前线程的中断状态。在第一种情况下,没有指定是否在释放锁之前发生中断测试。Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
awaitUninterruptibly
void awaitUninterruptibly()
Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者Condition
的 signalAll()
方法;或者Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
awaitNanos
long awaitNanos(long nanosTimeout)
throws InterruptedException
Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者Condition
的 signalAll()
方法;或者
InterruptedException
,并且清除当前线程的已中断状态。在第一种情况下,没有指定是否在释放锁之前发生中断测试。nanosTimeout
值的时间,如果超时,则返回一个小于等于 0 的值。可以用此值来确定在等待返回但某一等待条件仍不具备的情况下,是否要再次等待,以及再次等待的时间。此方法的典型用法采用以下形式: synchronized boolean aMethod(long timeout, TimeUnit unit) {
long nanosTimeout = unit.toNanos(timeout);
while (!conditionBeingWaitedFor) {
if (nanosTimeout > 0)
nanosTimeout = theCondition.awaitNanos(nanosTimeout);
else
return false;
}
// ...
}
Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常会抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
nanosTimeout
- 等待的最长时间,以毫微秒为单位nanosTimeout
值减去花费在等待此方法的返回结果的时间的估算。正值可以用作对此方法进行后续调用的参数,来完成等待所需时间结束。小于等于零的值表示没有剩余时间。InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
await
boolean await(long time,
TimeUnit unit)
throws InterruptedException
awaitNanos(unit.toNanos(time)) > 0
time
- 最长等待时间unit
- time
参数的时间单位false
,否则返回 true
InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
awaitUntil
boolean awaitUntil(Date deadline)
throws InterruptedException
Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者Condition
的 signalAll()
方法;或者
InterruptedException
,并且清除当前线程的已中断状态。在第一种情况下,没有指定是否在释放锁之前发生中断测试。 synchronized boolean aMethod(Date deadline) {
boolean stillWaiting = true;
while (!conditionBeingWaitedFor) {
if (stillWaiting)
stillWaiting = theCondition.awaitUntil(deadline);
else
return false;
}
// ...
}
Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
deadline
- 一直处于等待状态的绝对时间false
,否则返回 true
InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
signal
void signal()
await
返回之前,该线程必须重新获取锁。
signalAll
void signalAll()
await
返回之前,每个线程都必须重新获取锁。
以上是介面 Condition的詳細內容。更多資訊請關注PHP中文網其他相關文章!