ホームページ  >  記事  >  Java  >  インターフェースの状態

インターフェースの状態

巴扎黑
巴扎黑オリジナル
2017-06-26 11:26:571180ブラウズ

java.util.concurrent.locks インターフェース Condition

  • すべての既知の実装クラス:

  • AbstractQueuedLongSynchronizer.ConditionObject、AbstractQueuedSynchronizer.ConditionObject


public interface Condition
<br>

条件 は になりますオブジェクト 監視メソッド (waitnotify、および notifyAll) ConditionObject 监视器方法(waitnotifynotifyAll分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用

条件(也称为条件队列条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。

Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。

作为一个示例,假定有一个绑定的缓冲区,它支持 puttake 方法。如果试图在空的缓冲区上执行 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 语句中的目标,并且可以调用自己的 waitnotification 监视器方法。获取 Condition 实例的监视器锁或者使用其监视器方法,与获取和该 Condition 相关的 Lock 或使用其 waitingsignalling 方法没有什么特定的关系。为了避免混淆,建议除了在其自身的实现中之外,切勿以这种方式使用 Condition 实例。

除非另行说明,否则为任何参数传递 null 值将导致抛出 NullPointerException

实现注意事项

在等待 Condition 时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为 Condition個別のオブジェクトに分解します。

これらのオブジェクトは、

Lock 実装

と組み合わせて使用​​して、オブジェクトごとに複数の待機セット (待機セット) を提供します。その中で、

Locksynchronized メソッドとステートメントの使用を置き換え、Condition はオブジェクト モニター メソッドの使用を置き換えます

条件 (条件キュー または条件変数とも呼ばれます) は、特定の状態条件が true になる可能性があるときに別のスレッドに通知する意味をスレッドに提供します。以前は、スレッド一時停止されました (つまり、「待機」させられました)。この共有状態情報へのアクセスは別のスレッドで発生するため、保護する必要があるため、何らかの形式のロックが条件に関連付けられます。条件が指定された待機の主なプロパティは、Object.wait と同様に、 関連するロックをアトミックに解放し、現在のスレッドを一時停止することです。 🎜🎜🎜Condition インスタンスは基本的にロックにバインドされています。特定の 🎜Lock🎜 インスタンスの Condition インスタンスを取得するには、その 🎜newCondition()🎜 メソッドを使用します。 🎜🎜🎜例として、put メソッドと take メソッドをサポートするバインド バッファがあると仮定します。空のバッファーで take 操作を実行しようとすると、項目が使用可能になるまでスレッドはブロックされます。また、満杯のバッファーで put 操作を実行しようとすると、スレッドはブロックされます。スレッドはアイテムが使用可能になるまでブロックされます。> 操作の場合、スレッドはスペースが使用可能になるまでブロックされます。私たちは put スレッドと take スレッドを別々の待機セットに保持して、バッファー内の項目またはスペースが使用可能になったときに最適なプランを活用できるようにすることを好みます。一度に 1 つのスレッドのみを通知します。これは、2 つの Condition インスタンスを使用して実行できます。 🎜
void await()
           throws InterruptedException
🎜 (ArrayBlockingQueue クラスはこの機能を提供するため、このサンプル クラスを実装する理由はありません。) 🎜🎜Condition 実装は、Object とは異なる機能を提供できます。 code> 通知の順序の保証や、通知の実行中にロックを保持する必要性など、モニター メソッドの動作とセマンティクス。実装がそのような特別なセマンティクスを提供する場合、実装はこれらのセマンティクスを文書化しなければなりません (MUST)。 🎜🎜 Condition インスタンスは、それ自体が synchronized ステートメントのターゲットとして使用でき、独自の wait および を呼び出すことができる単なる通常のオブジェクトであることに注意してください。 >notification 監視メソッド。 Condition インスタンスのモニター ロックを取得するか、そのモニター メソッドを使用し、Condition に関連付けられた Lock を取得するか、その waiting を使用します。 は、signalling メソッドと特別な関係はありません。混乱を避けるため、 Condition インスタンスは、独自の実装内以外では決してこの方法で使用しないことをお勧めします。 🎜🎜特に明記されていない限り、パラメータに null 値を渡すと、NullPointerException がスローされます。 🎜

実装メモ

🎜 通常、基盤となるプラットフォーム セマンティクスへの譲歩として、Condition の待機中に「偽ウェイク」が発生することを許可します。 Condition は常にループ内で待機し、待機中の状態ステートメントをテストする必要があるため、ほとんどのアプリケーションでは、これは実際的な影響はほとんどありません。実装では、発生する可能性のある偽のウェイクアップを自由に削除できますが、アプリケーション プログラマは、これらの偽のウェイクアップが発生する可能性があることを常に想定し、常にループ内で待機することをお勧めします。 🎜🎜一部のプラットフォームでの 3 つの形式の条件付き待機 (中断可能、中断不可能、タイムアウト) の実装とそのパフォーマンス特性は異なる場合があります。特に、これらの機能を提供し、順序保証などの特定のセマンティクスを維持することは困難な場合があります。さらに、🎜、スレッドの実際の一時停止を中断する機能は、すべてのプラットフォームで常に可能であるとは限りません。 🎜🎜🎜 したがって、実装では、3 つの待機形式すべてに対してまったく同じ保証やセマンティクスを定義する必要はなく、また、割り込みスレッドの実際の一時停止をサポートする必要もありません。 🎜🎜 実装では、各待機メソッドによって提供されるセマンティクスと保証を明確に文書化する必要があります。実装が割り込みスレッドの一時停止をサポートしていない場合は、このインターフェイスで定義された割り込みセマンティクスに準拠する必要があります。 🎜

通常、割り込みはキャンセルを意味し、割り込みチェックは通常ほとんど実行されないため、実装は通常のメソッドが戻る前に割り込みに応答できます。これは、別の操作の後に発生する割り込みによってスレッド ロックが解放される場合にも当てはまります。実装ではこの動作を文書化する必要があります。

  • 開始元:

  • 1.5


<br>

シグナルを受信するか中断されるまで、現在のスレッドを待機状態にします。
メソッドの概要
void 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>() &lt;br&gt;await<span style="font-size: 14px">()</span>

<br>boolean

<tr class="TableHeadingColor">await<th align="left">(long time, TimeUnit単位) <span style="font-size: small"><strong></strong> を受信した後に現在のスレッドを中断させます。信号 または、指定された待ち時間に達するまで待ち状態になります。 </span> </th> </tr>
🎜long🎜🎜🎜🎜awaitNanos🎜(long nanosTimeout) 🎜🎜🎜 現在のスレッドがシグナルを受信する、中断される、または到達するようにします。指定した時間 待ち時間まで待っています。 🎜🎜🎜🎜🎜🎜 void🎜🎜 🎜🎜awaitUninterruptibly🎜() 🎜🎜🎜 現在のスレッドがシグナルを受信するまで待機します。 🎜🎜🎜🎜🎜🎜boolean🎜🎜 🎜🎜awaitUntil🎜(日付期限) 🎜🎜🎜 現在のスレッドがシグナルを受信する、中断される、または到達するようにします。指定された時刻 期限が保留中です。 🎜🎜🎜🎜🎜🎜 void🎜🎜 🎜🎜signal🎜() 🎜🎜🎜 待機中のスレッドを起動します。 🎜🎜🎜🎜🎜🎜 void🎜🎜 🎜🎜signalAll🎜() 🎜🎜🎜 待機中のすべてのスレッドを起動します。 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜方法の詳細🎜🎜🎜🎜🎜🎜

<br>

await

void await()
           throws InterruptedException
  • 造成当前线程在接到信号或被中断之前一直处于等待状态。

    与此 Condition 相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一 以前,当前线程将一直处于休眠状态:

    • 其他某个线程调用此 Conditionsignal() 方法,并且碰巧将当前线程选为被唤醒的线程;或者

    • 其他某个线程调用此 ConditionsignalAll() 方法;或者

    • 其他某个线程中断当前线程,且支持中断线程的挂起;或者

    • 发生“虚假唤醒

    在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。

    如果当前线程:

    • 在进入此方法时已经设置了该线程的中断状态;或者

    • 在支持等待和中断线程挂起时,线程被中断,

    则抛出 InterruptedException,并清除当前线程的中断状态。在第一种情况下,没有指定是否在释放锁之前发生中断测试。

    实现注意事项

    假定调用此方法时,当前线程保持了与此 Condition 有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException)并且该实现必须对此进行记录。

    与响应某个信号而返回的普通方法相比,实现可能更喜欢响应某个中断。在这种情况下,实现必须确保信号被重定向到另一个等待线程(如果有的话)。

     

     

    • 抛出:

    • InterruptedException - 如果当前线程被中断(并且支持中断线程挂起)


<br>

awaitUninterruptibly

void awaitUninterruptibly()
  • 造成当前线程在接到信号之前一直处于等待状态。

    与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下三种情况之一 以前,当前线程将一直处于休眠状态:

    • 其他某个线程调用此 Conditionsignal() 方法,并且碰巧将当前线程选为被唤醒的线程;或者

    • 其他某个线程调用此 ConditionsignalAll() 方法;或者

    • 发生“虚假唤醒

    在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。

    如果在进入此方法时设置了当前线程的中断状态,或者在等待时,线程被中断,那么在接到信号之前,它将继续等待。当最终从此方法返回时,仍然将设置其中断状态。

    实现注意事项

    假定调用此方法时,当前线程保持了与此 Condition 有关联的锁。这取决于确定是否为这种情况以及不是时,如何对此作出响应的实现。通常,将抛出一个异常(比如 IllegalMonitorStateException)并且该实现必须对此进行记录。

     


<br>

awaitNanos

long awaitNanos(long nanosTimeout)
                throws InterruptedException
  • 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。

    与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下五种情况之一 以前,当前线程将一直处于休眠状态:

    • 其他某个线程调用此 Conditionsignal() 方法,并且碰巧将当前线程选为被唤醒的线程;或者

    • 其他某个线程调用此 ConditionsignalAll() 方法;或者

    • 其他某个线程中断当前线程,且支持中断线程的挂起;或者

    • 已超过指定的等待时间;或者

    • 发生“虚假唤醒”。

    在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。

    如果当前线程:

    • 在进入此方法时已经设置了该线程的中断状态;或者

    • 在支持等待和中断线程挂起时,线程被中断,

    则抛出 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>

await

boolean await(long time,
              TimeUnit unit)
              throws InterruptedException
  • 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。此方法在行为上等效于:

       awaitNanos(unit.toNanos(time)) > 0

     

    • 参数:

    • time - 最长等待时间

    • unit - time 参数的时间单位

    • 返回:

    • 如果在从此方法返回前检测到等待时间超时,则返回 false,否则返回 true

    • 抛出:

    • InterruptedException - 如果当前线程被中断(并且支持中断线程挂起)


<br>

awaitUntil

boolean awaitUntil(Date deadline)
                   throws InterruptedException
  • 造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。

    与此条件相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下五种情况之一 以前,当前线程将一直处于休眠状态:

    • 其他某个线程调用此 Conditionsignal() 方法,并且碰巧将当前线程选为被唤醒的线程;或者

    • 其他某个线程调用此 ConditionsignalAll() 方法;或者

    • 其他某个线程中断当前线程,且支持中断线程的挂起;或者

    • 指定的最后期限到了;或者

    • 发生“虚假唤醒”。

    在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证 它保持此锁。

    如果当前线程:

    • 在进入此方法时已经设置了该线程的中断状态;或者

    • 在支持等待和中断线程挂起时,线程被中断,

    则抛出 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>

signal

void signal()
  • 唤醒一个等待线程。

    如果所有的线程都在等待此条件,则选择其中的一个唤醒。在从 await 返回之前,该线程必须重新获取锁。

     


<br>

signalAll

void signalAll()
  • 唤醒所有等待线程。

    如果所有的线程都在等待此条件,则唤醒所有线程。在从 await 返回之前,每个线程都必须重新获取锁。

以上がインターフェースの状態の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。