알려진 모든 구현 클래스:
AbstractQueuedLongSynchronizer.ConditionObject, AbstractQueuedSynchronizer.ConditionObject
public interface Condition
<br>
Condition 코드>는 입니다. 개체
모니터 메서드(wait
, notify
및 notifyAll
) Condition
将 Object
监视器方法(wait
、notify
和 notifyAll
)分解成截然不同的对象,以便通过将这些对象与任意 Lock
实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock
替代了 synchronized
方法和语句的使用,Condition
替代了 Object 监视器方法的使用。
条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait
做的那样。
Condition
实例实质上被绑定到一个锁上。要为特定 Lock
实例获得 Condition
实例,请使用其 newCondition()
方法。
作为一个示例,假定有一个绑定的缓冲区,它支持 put
和 take
方法。如果试图在空的缓冲区上执行 take
操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put
操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put
线程和 take
线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition
实例来做到这一点。
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
(ArrayBlockingQueue
类提供了这项功能,因此没有理由去实现这个示例类。)
Condition
实现可以提供不同于 Object
监视器方法的行为和语义,比如受保证的通知排序,或者在执行通知时不需要保持一个锁。如果某个实现提供了这样特殊的语义,则该实现必须记录这些语义。
注意,Condition
实例只是一些普通的对象,它们自身可以用作 synchronized
语句中的目标,并且可以调用自己的 wait
和 notification
监视器方法。获取 Condition
实例的监视器锁或者使用其监视器方法,与获取和该 Condition
相关的 Lock
或使用其 waiting
和 signalling
方法没有什么特定的关系。为了避免混淆,建议除了在其自身的实现中之外,切勿以这种方式使用 Condition
实例。
除非另行说明,否则为任何参数传递 null
值将导致抛出 NullPointerException
。
在等待 Condition
时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为 Condition
개별 개체로 분해하여
Lock
구현
Lock
은 동기화
메서드 및 문의 사용을 대체하고, Condition
은 개체 모니터 메서드
Object.wait
와 마찬가지로 원자적으로 관련 잠금을 해제하고 현재 스레드를 일시 중단하는 것입니다. 🎜🎜🎜Condition
인스턴스는 기본적으로 잠금에 바인딩되어 있습니다. 특정 🎜Lock
🎜 인스턴스에 대한 Condition
인스턴스를 얻으려면 해당 🎜newCondition()
🎜 메서드를 사용하세요. 🎜🎜🎜예를 들어 put
및 take
메서드를 지원하는 바운드 버퍼가 있다고 가정합니다. 빈 버퍼에서 take
작업을 수행하려고 하면 항목이 사용 가능해질 때까지 스레드가 차단됩니다. 항목을 사용할 수 있을 때까지 스레드가 차단됩니다. > 작업을 수행하면 공간을 사용할 수 있을 때까지 스레드가 차단됩니다. 우리는 버퍼의 항목이나 공간을 사용할 수 있을 때 최상의 계획을 활용할 수 있도록 put
스레드와 take
스레드를 별도의 대기 세트에 유지하는 것을 좋아합니다. 한 번에 하나의 스레드에만 알립니다. 이는 두 개의 Condition
인스턴스를 사용하여 수행할 수 있습니다. 🎜void await() throws InterruptedException🎜 (
ArrayBlockingQueue
클래스가 이 기능을 제공하므로 이 예제 클래스를 구현할 이유가 없습니다.) 🎜🎜Condition
구현은 Object와 다른 기능을 제공할 수 있습니다.
code> 알림 순서 보장 또는 알림 실행 중 잠금 유지 필요성과 같은 모니터 메서드의 동작 및 의미 체계입니다. 구현이 그러한 특별한 의미를 제공하는 경우 구현은 이러한 의미를 문서화해야 합니다. 🎜🎜 Condition
인스턴스는 synchronized
문에서 대상으로 사용할 수 있고 자체 wait
및 알림
모니터링 방법. Condition
인스턴스의 모니터 잠금을 얻거나 해당 모니터 메서드를 사용하고, Condition
과 연결된 Lock
을 얻거나 대기 중을 사용합니다.
는 signalling
메소드와 특별한 관계가 없습니다. 혼란을 피하기 위해 Condition
인스턴스는 자체 구현 내에서를 제외하고 이러한 방식으로 사용되지 않는 것이 좋습니다. 🎜🎜별도의 언급이 없는 한, 매개변수에 null
값을 전달하면 NullPointerException
이 발생합니다. 🎜조건
을 기다리는 동안 "거짓 깨우기"가 발생하도록 허용합니다. 일반적으로 기본 플랫폼 의미 체계에 대한 양보입니다. 대부분의 애플리케이션에서는 Condition
이 항상 루프에서 기다려야 하고 대기 중인 상태 문을 테스트해야 하므로 이는 실질적인 영향을 거의 미치지 않습니다. 구현 시 허위 웨이크업을 자유롭게 제거할 수 있지만 애플리케이션 프로그래머는 항상 이러한 허위 웨이크업이 발생할 수 있다고 가정하고 루프에서 대기하는 것이 좋습니다. 🎜🎜일부 플랫폼에서는 세 가지 형태의 조건부 대기(중단 가능, 중단 불가능, 시간 초과) 구현과 성능 특성이 다를 수 있습니다. 특히 이러한 기능을 제공하고 주문 보장과 같은 특정 의미를 유지하는 것이 어려울 수 있습니다. 또한 🎜 스레드가 실제로 일시 중지되는 것을 중단하는 기능이 모든 플랫폼에서 항상 가능한 것은 아닙니다. 🎜🎜🎜따라서 구현에서는 세 가지 대기 형태 모두에 대해 정확히 동일한 보장이나 의미를 정의할 필요가 없으며 인터럽트 스레드의 실제 일시 중단을 지원할 필요도 없습니다. 🎜🎜 구현에서는 각 대기 메서드에서 제공하는 의미와 보장을 명확하게 문서화해야 합니다. 구현이 인터럽트 스레드 일시 중지를 지원하지 않는 경우 이 인터페이스에 정의된 인터럽트 의미를 준수해야 합니다. 🎜인터럽트는 일반적으로 취소를 의미하고 인터럽트 검사는 일반적으로 거의 수행되지 않으므로 구현에서는 일반 메서드가 반환되기 전에 인터럽트에 응답할 수 있습니다. 이는 다른 작업 후에 발생하는 인터럽트가 스레드 잠금을 해제할 수 있는 경우에도 마찬가지입니다. 구현에서는 이 동작을 문서화해야 합니다.
시작:
1.5
<br>
방법 요약 | ||
---|---|---|
무효 void |
<strong>await</strong>() <br> 造成当前线程在接到信号或被中断之前一直处于等待状态。
|
|
boolean |
<strong>await</strong>(long time, TimeUnit unit) <br> 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
|
|
long |
<strong>awaitNanos</strong>(long nanosTimeout) <br> 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
|
|
void |
<strong>awaitUninterruptibly</strong>() <br> 造成当前线程在接到信号之前一直处于等待状态。
|
|
boolean |
<strong>awaitUntil</strong>(Date deadline) <br> 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
|
|
void |
<strong>signal</strong>() <br> 唤醒一个等待线程。
|
|
void |
<strong>signalAll</strong>() |
<br> <span style="font-size: 14px">await</span>() |
<br>
boolean
long
🎜🎜🎜awaitNanos🎜(long nanosTimeout)
🎜🎜🎜 현재 스레드가 신호를 받거나 중단되거나 도달하도록 합니다. 지정된 시간 대기 시간까지 기다리고 있었습니다. 🎜🎜🎜🎜🎜🎜 void
🎜🎜🎜awaitUninterruptously🎜()
🎜🎜🎜 현재 스레드가 신호를 받을 때까지 기다리게 합니다. 🎜🎜🎜🎜🎜🎜boolean
🎜🎜🎜awaitUntil🎜(날짜 기한)
🎜🎜🎜 현재 스레드가 신호를 받거나 중단되거나 지정된 시간에 도달 마감일이 보류되었습니다. 🎜🎜🎜🎜🎜🎜 void
🎜🎜🎜signal🎜()
🎜🎜🎜 대기 스레드를 깨웁니다. 🎜🎜🎜🎜🎜🎜 void
🎜🎜🎜signalAll🎜()
🎜🎜🎜 모든 대기 스레드를 깨웁니다. 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜방법 세부정보🎜🎜🎜🎜🎜🎜<br>
void await() throws InterruptedException
造成当前线程在接到信号或被中断之前一直处于等待状态。
与此 Condition
相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一 以前,当前线程将一直处于休眠状态:
其他某个线程调用此 Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者
其他某个线程调用此 Condition
的 signalAll()
方法;或者
其他某个线程中断当前线程,且支持中断线程的挂起;或者
发生“虚假唤醒”
在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。
如果当前线程:
在进入此方法时已经设置了该线程的中断状态;或者
在支持等待和中断线程挂起时,线程被中断,
则抛出 InterruptedException
,并清除当前线程的中断状态。在第一种情况下,没有指定是否在释放锁之前发生中断测试。
实现注意事项
假定调用此方法时,当前线程保持了与此 Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
与响应某个信号而返回的普通方法相比,实现可能更喜欢响应某个中断。在这种情况下,实现必须确保信号被重定向到另一个等待线程(如果有的话)。
抛出:
InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
<br>
void awaitUninterruptibly()
造成当前线程在接到信号之前一直处于等待状态。
与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下三种情况之一 以前,当前线程将一直处于休眠状态:
其他某个线程调用此 Condition
的 signal()
方法,并且碰巧将当前线程选为被唤醒的线程;或者
其他某个线程调用此 Condition
的 signalAll()
方法;或者
发生“虚假唤醒”
在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。
如果在进入此方法时设置了当前线程的中断状态,或者在等待时,线程被中断,那么在接到信号之前,它将继续等待。当最终从此方法返回时,仍然将设置其中断状态。
实现注意事项
假定调用此方法时,当前线程保持了与此 Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
<br>
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; } // ... }
设计注意事项:此方法需要一个 nanosecond 参数,以避免在报告剩余时间时出现截断错误。在发生重新等待时,这种精度损失使得程序员难以确保总的等待时间不少于指定等待时间。
实现注意事项
假定调用此方法时,当前线程保持了与此 Condition
有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常会抛出一个异常(比如 IllegalMonitorStateException
)并且该实现必须对此进行记录。
与响应某个信号而返回的普通方法相比,或者与指示所使用的指定等待时间相比,实现可能更喜欢响应某个中断。在任意一种情况下,实现必须确保信号被重定向到另一个等待线程(如果有的话)。
参数:
nanosTimeout
- 等待的最长时间,以毫微秒为单位
返回:
nanosTimeout
值减去花费在等待此方法的返回结果的时间的估算。正值可以用作对此方法进行后续调用的参数,来完成等待所需时间结束。小于等于零的值表示没有剩余时间。
抛出:
InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
<br>
boolean await(long time, TimeUnit unit) throws InterruptedException
造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。此方法在行为上等效于:
awaitNanos(unit.toNanos(time)) > 0
参数:
time
- 最长等待时间
unit
- time
参数的时间单位
返回:
如果在从此方法返回前检测到等待时间超时,则返回 false
,否则返回 true
抛出:
InterruptedException
- 如果当前线程被中断(并且支持中断线程挂起)
<br>
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
- 如果当前线程被中断(并且支持中断线程挂起)
<br>
void signal()
唤醒一个等待线程。
如果所有的线程都在等待此条件,则选择其中的一个唤醒。在从 await
返回之前,该线程必须重新获取锁。
<br>
void signalAll()
唤醒所有等待线程。
如果所有的线程都在等待此条件,则唤醒所有线程。在从 await
返回之前,每个线程都必须重新获取锁。
위 내용은 인터페이스 조건의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!