java thread signal_java — Thread之CountDownLatch的使用
CountDownLatch的簡單使用
CountDownLatch的簡單介紹:
CountDownLatch類是一個同步計數(shù)器,構(gòu)造時傳入int參數(shù),該參數(shù)就是計數(shù)器的初始值,每調(diào)用一次countDown()方法,計數(shù)器減1,計數(shù)器大于0 時,await()方法會阻塞程序繼續(xù)執(zhí)行
CountDownLatch是一個倒計數(shù)的鎖存器,當(dāng)計數(shù)減至0時觸發(fā)特定的事件。
CountDownLatch被用來同步一個或多個任務(wù),強(qiáng)制它們等待由其他任務(wù)執(zhí)行的一組操作完成。你可以向CountDownLatch對象設(shè)置一個初始計數(shù)值,任何在這個對象上調(diào)用wait()方法都將阻塞,直至這個計數(shù)值達(dá)到0。其他任務(wù)在結(jié)束工作時,可以在該對象上調(diào)用湊你countDown()來減小這個計數(shù)值。CountDownLatch被設(shè)計為只觸發(fā)一次,計數(shù)值不能被重置。如果你需要能夠重置計數(shù)值的版本,則可以使用CyclicBarrier。
以下是jdk文檔上的兩個例子,我們可以學(xué)習(xí)一下。
一、開始信號,阻止任何工人進(jìn)行,直到司機(jī)準(zhǔn)備好他們繼續(xù)進(jìn)行
package com.linux.huhx.concurreny;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Driver1 {
public static void main(String[] args) throws Exception {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(5);
for (int i = 0; i < 5; ++i) // create and start threads
new Thread(new TaskWorker(startSignal, doneSignal)).start();
System.out.println("countDown before."); // don't let run yet
startSignal.countDown(); // let all threads proceed
TimeUnit.SECONDS.sleep(1);
System.out.println("await before");
/**
* 1、由于doneSignal里面的初始count=5,所以主線程在此會阻塞。
* 2、當(dāng)所有的子線程執(zhí)行完(doneSignal.countDown())之后,此時的count=0。所以后面代碼可以繼續(xù)執(zhí)行。
*/
doneSignal.await();
System.out.println("await after");
}
private static class TaskWorker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
public TaskWorker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
@Override
public void run() {
try {
/**
* 1、剛進(jìn)來的時候,由于startSignal的count=1。所以await()方法阻塞于此。
* 2、當(dāng)主線程執(zhí)行了startSignal.countDown();此時的startSignal的count=0。所以子線程可以正常運(yùn)行。
*/
startSignal.await();
doSomeWork();
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doSomeWork() {
System.out.println("in run method: " + Thread.currentThread().getName());
}
}
}
執(zhí)行的結(jié)果如下:子線程的執(zhí)行順序不固定
countDown before.
in run method: Thread-0
in run method: Thread-1
in run method: Thread-2
in run method: Thread-4
in run method: Thread-3
await before
await after
調(diào)用countDown()的任務(wù)在產(chǎn)生這個調(diào)用時并沒有阻塞,只有對await()的調(diào)用會被阻塞,直至計數(shù)值到達(dá)0。
二、完成信號,允許司機(jī)等到所有工人完成為止
package com.linux.huhx.concurreny;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Driver2 {
public static void main(String[] args) throws Exception {
CountDownLatch doneSignal = new CountDownLatch(5);
ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; ++i) // create and start threads
service.execute(new WorkerRunnable(doneSignal, i));
System.out.println("await before");
doneSignal.await();
System.out.println("await after");
service.shutdown();
}
private static class WorkerRunnable implements Runnable {
private final CountDownLatch doneSignal;
private final int i;
public WorkerRunnable(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
}
@Override
public void run() {
doWork(i);
try {
Thread.sleep(new Random().nextInt(1000));
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doWork(int i) {
System.out.println("in run method: " + i + " " + Thread.currentThread().getName());
}
}
}
運(yùn)行的結(jié)果如下:子線程的執(zhí)行順序不固定
await before
in run method: 0 pool-1-thread-1
in run method: 2 pool-1-thread-3
in run method: 1 pool-1-thread-2
in run method: 3 pool-1-thread-1
in run method: 4 pool-1-thread-2
await after
總結(jié)
以上是生活随笔為你收集整理的java thread signal_java — Thread之CountDownLatch的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java stw_JVM STW里的no
- 下一篇: 获取中位数java_java 计算中位