Java并发编程:CountDownLatch线程等待同步辅助类 傷城~ 2021-10-13 00:23 345阅读 0赞 原文地址:[https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html][https_docs.oracle.com_javase_7_docs_api_java_util_concurrent_CountDownLatch.html] java.util.concurrent中 ## CountDownLatch类 ## * [java.lang.Object继承][java.lang.Object] * java.util.concurrent.CountDownLatch * -------------------- 公共类CountDownLatch 扩展了Object ** 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。** * A `CountDownLatch`用给定的*计数*初始化。由于[`await`][await]方法的调用,方法阻塞直到当前计数达到零[`countDown()`][countDown],之后释放所有等待的线程并[`await`][await]立即返回任何后续的调用 。这是一次性现象 - 计数无法重置。如果您需要重置计数的版本,请考虑使用[`CyclicBarrier`][CyclicBarrier]。 A `CountDownLatch`是一种通用的同步工具,可用于多种用途。甲 `CountDownLatch`一个的计数初始化作为一个简单的开/关锁存器,或门:所有线程调用[`await`][await] ,直到它被一个线程调用开在栅极等待[`countDown()`][countDown]。一个`CountDownLatch`初始化为*ň* 可以用来做一个线程等待,直到*ň*线程完成一些动作,或某些动作已经完成N次。 a的一个有用属性`CountDownLatch`是它不需要线程调用`countDown`等待计数在继续之前达到零,它只是阻止任何线程继续经过[`await`][await]直到所有线程都可以通过。 **示例用法:**这是一对类,其中一组工作线程使用两个倒计时锁存器: * 第一个是启动信号,阻止任何工人继续工作,直到驱动程序准备好继续进行; * 第二个是完成信号,允许驾驶员等到所有工人完成。 class Driver { // ... void main() throws InterruptedException { CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // create and start threads new Thread(new Worker(startSignal, doneSignal)).start(); doSomethingElse(); // don't let run yet startSignal.countDown(); // let all threads proceed doSomethingElse(); doneSignal.await(); // wait for all to finish } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } public void run() { try { startSignal.await(); doWork(); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } void doWork() { ... } } 另一个典型的用法是将问题分成N个部分,用执行该部分的Runnable描述每个部分并对锁存器进行倒计时,并将所有Runnables排队到Executor。当所有子部件都完成后,协调线程将能够通过等待。(当线程必须以这种方式重复倒计时,而是使用a [`CyclicBarrier`][CyclicBarrier]。) class Driver2 { // ... void main() throws InterruptedException { CountDownLatch doneSignal = new CountDownLatch(N); Executor e = ... for (int i = 0; i < N; ++i) // create and start threads e.execute(new WorkerRunnable(doneSignal, i)); doneSignal.await(); // wait for all to finish } } class WorkerRunnable implements Runnable { private final CountDownLatch doneSignal; private final int i; WorkerRunnable(CountDownLatch doneSignal, int i) { this.doneSignal = doneSignal; this.i = i; } public void run() { try { doWork(i); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } void doWork() { ... } } 内存一致性影响:在计数达到零之前,调用之前的线程中的 操作`countDown()` [*发生在*][Link 1]从`await()`另一个线程中的对应成功返回[*之后的*][Link 1]操作 [*之前*][Link 1]。 **以来:** 1.5 * ### 方法摘要 ### <table> <span style="color:#353833;">方法 </span> <tbody> <tr> <th style="text-align:left;vertical-align:top;width:429px;"><span style="color:#353833;">修饰符和类型</span></th> <th style="text-align:left;vertical-align:top;"><span style="color:#353833;">方法和描述</span></th> </tr> <tr> <td style="text-align:left;vertical-align:top;width:446px;"><span style="color:#353833;"><code>void</code></span></td> <td style="text-align:left;vertical-align:top;"><span style="color:#353833;"><code><strong><a rel="nofollow">await</a></strong>()</code></span> <p><span style="color:#353833;">除非线程被<a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29" rel="nofollow">中断</a>,否则导致当前线程等待锁存器倒计数到零。</span></p> </td> </tr> <tr> <td style="text-align:left;vertical-align:top;width:446px;"><span style="color:#353833;"><code>boolean</code></span></td> <td style="text-align:left;vertical-align:top;"><span style="color:#353833;"><code><strong><a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html#await%28long,%20java.util.concurrent.TimeUnit%29" rel="nofollow">await</a></strong>(long timeout, <a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/TimeUnit.html" rel="nofollow">TimeUnit</a> unit)</code></span> <p><span style="color:#353833;">导致当前线程等待,直到锁存器倒计数到零,除非线程被<a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29" rel="nofollow">中断</a>,或者指定的等待时间过去。</span></p> </td> </tr> <tr> <td style="text-align:left;vertical-align:top;width:446px;"><span style="color:#353833;"><code>void</code></span></td> <td style="text-align:left;vertical-align:top;"><span style="color:#353833;"><code><strong><a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html#countDown%28%29" rel="nofollow">countDown</a></strong>()</code></span> <p><span style="color:#353833;">减少锁存器的计数,如果计数达到零则释放所有等待的线程。</span></p> </td> </tr> <tr> <td style="text-align:left;vertical-align:top;width:446px;"><span style="color:#353833;"><code>long</code></span></td> <td style="text-align:left;vertical-align:top;"><span style="color:#353833;"><code><strong><a rel="nofollow">getCount</a></strong>()</code></span> <p><span style="color:#353833;">返回当前计数。</span></p> </td> </tr> <tr> <td style="text-align:left;vertical-align:top;width:446px;"><span style="color:#353833;"><code><a href="https://docs.oracle.com/javase/7/docs/api/java/lang/String.html" rel="nofollow">String</a></code></span></td> <td style="text-align:left;vertical-align:top;"><span style="color:#353833;"><code><strong><a rel="nofollow">toString</a></strong>()</code></span> <p><span style="color:#353833;">返回标识此锁存器的字符串及其状态。</span></p> </td> </tr> </tbody> </table> * ### 从类java.lang继承的方法。[宾语][java.lang.Object] ### `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait` * ### 构造函数摘要 ### <table> <span style="color:#353833;">构造函数 </span> <tbody> <tr> <th style="border-color:#9eadc0;text-align:left;vertical-align:top;"><span style="color:#353833;">构造函数和描述</span></th> </tr> <tr> <td style="text-align:left;vertical-align:top;"><span style="color:#353833;"><code><strong><a rel="nofollow">CountDownLatch</a></strong>(int count)</code></span> <p><span style="color:#353833;"><code>CountDownLatch</code>使用给定计数构造初始化。</span></p> </td> </tr> </tbody> </table> * ### 方法细节 ### * 等待 public void await() 抛出InterruptedException 除非线程被[中断][Link 2],否则导致当前线程等待锁存器倒计数到零。 如果当前计数为零,则此方法立即返回。 如果当前计数大于零,则当前线程将被禁用以进行线程调度,并且在发生以下两种情况之一之前处于休眠状态: * 由于[`countDown()`][countDown]方法的调用,计数达到零 ; 要么 * 其他一些线程会[中断][Link 2] 当前线程。 如果当前线程: * 在进入此方法时设置其中断状态; 要么 * 在等待时 被[打断][Link 2] [`InterruptedException`][InterruptedException]抛出 然后清除当前线程的中断状态。 **抛出:** `InterruptedException` - 如果当前线程在等待时被中断 * 等待 public boolean await(long timeout, TimeUnit unit) 抛出InterruptedException 导致当前线程等待,直到锁存器倒计数到零,除非线程被[中断][Link 2],或者指定的等待时间过去。 如果当前计数为零,则此方法立即返回值`true`。 如果当前计数大于零,则当前线程因线程调度而被禁用,并且在发生以下三种情况之一之前处于休眠状态: * 由于`countDown()`方法的调用,计数达到零 ; 要么 * 其他一些线程会[中断][Link 2] 当前线程; 要么 * 指定的等待时间过去了。 如果计数达到零,则该方法返回值`true`。 如果当前线程: * 在进入此方法时设置其中断状态; 要么 * 在等待时 被[打断][Link 2] [`InterruptedException`][InterruptedException]抛出 然后清除当前线程的中断状态。 如果指定的等待时间过去,则`false` 返回该值。如果时间小于或等于零,则该方法将不会等待。 **参数:** `timeout` - 等待的最长时间 `unit`\- `timeout`参数的时间单位 **返回:** `true`如果计数达到零并且`false` 在计数达到零之前等待时间已过去 **抛出:** `InterruptedException` - 如果当前线程在等待时被中断 * 倒数 public void countDown() 减少锁存器的计数,如果计数达到零则释放所有等待的线程。 如果当前计数大于零,则递减。如果新计数为零,则重新启用所有等待线程以进行线程调度。 如果当前计数等于零,则没有任何反应。 * getCount将 public long getCount() 返回当前计数。 此方法通常用于调试和测试目的。 **返回:** 目前的数量 * public String toString() 返回标识此锁存器的字符串及其状态。括号中的状态包括String `"Count ="` 后跟当前计数。 **覆盖:** `toString` 在班上 `Object` **返回:** 标识此锁存器的字符串及其状态 * ### 构造函数详细信息 ### * CountDownLatch public CountDownLatch(int count) `CountDownLatch`使用给定计数构造初始化。 **参数:** `count`\- [`countDown()`][countDown]线程可以通过之前必须调用的次数[`await()`][await] **抛出:** `IllegalArgumentException`\- 如果`count`是否定的 [https_docs.oracle.com_javase_7_docs_api_java_util_concurrent_CountDownLatch.html]: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html [java.lang.Object]: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html [await]: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html#await%28%29 [countDown]: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html#countDown%28%29 [CyclicBarrier]: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html [Link 1]: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility [Link 2]: https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29 [InterruptedException]: https://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html
还没有评论,来说两句吧...