- 論壇徽章:
- 0
|
java.util.concurrent
類 CountDownLatch
java.lang.Object
java.util.concurrent.CountDownLatch
一個同步輔助類,在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個或多個線程一直等待。
用給定的計數(shù) 初始化 CountDownLatch。由于調(diào)用了 countDown() 方法,所以在當(dāng)前計數(shù)到達(dá)零之前,await 方法會一直受阻塞。之后,會釋放所有等待的線程,await 的所有后續(xù)調(diào)用都將立即返回。這種現(xiàn)象只出現(xiàn)一次——計數(shù)無法被重置。如果需要重置計數(shù),請考慮使用 CyclicBarrier。
在一些應(yīng)用場合中,需要等待某個條件達(dá)到要求后才能做后面的事情;同時當(dāng)線程都完成后也會觸發(fā)事件,以便進(jìn)行后面的操作。 這個時候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒數(shù)一次,后者是等待倒數(shù)到0,如果沒有到達(dá)0,就只有阻塞等待了。
ountDown
public void countDown()
遞減鎖存器的計數(shù),如果計數(shù)到達(dá)零,則釋放所有等待的線程。如果當(dāng)前計數(shù)大于零,則將計數(shù)減少。如果新的計數(shù)為零,出于線程調(diào)度目的,將重新啟用所有的等待線程。
如果當(dāng)前計數(shù)等于零,則不發(fā)生任何操作。
await
public boolean await(long timeout,
TimeUnit unit)
throws InterruptedException
使當(dāng)前線程在鎖存器倒計數(shù)至零之前一直等待,除非線程被中斷或超出了指定的等待時間。如果當(dāng)前計數(shù)為零,則此方法立刻返回true 值。
如果當(dāng)前計數(shù)大于零,則出于線程調(diào)度目的,將禁用當(dāng)前線程,且在發(fā)生以下三種情況之一前,該線程將一直處于休眠狀態(tài):
• 由于調(diào)用 countDown() 方法,計數(shù)到達(dá)零;或者
• 其他某個線程中斷當(dāng)前線程;或者
• 已超出指定的等待時間。
如果計數(shù)到達(dá)零,則該方法返回 true 值。
如果當(dāng)前線程:
• 在進(jìn)入此方法時已經(jīng)設(shè)置了該線程的中斷狀態(tài);或者
• 在等待時被中斷,
則拋出 InterruptedException,并且清除當(dāng)前線程的已中斷狀態(tài)。如果超出了指定的等待時間,則返回值為 false。如果該時間小于等于零,則此方法根本不會等待。
countDownLatch 線程輔助類,是一個線程計數(shù)類,用來線程同步,每當(dāng)一個線程執(zhí)行完成后,就是加1,當(dāng)達(dá)到計數(shù),就算執(zhí)行完成。初始值必須小于等于要執(zhí)行的線程數(shù),為0 是,不其作用,大于0,小于等于線程數(shù)時,為同步線程數(shù),當(dāng)大于線程數(shù)時,為死循環(huán)(可能不對)反正就是一直等待。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
public class T1 {
final static SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(3);
Worker w1 = new Worker("w1", 2000, countDownLatch);
Worker w2 = new Worker("w2", 5000, countDownLatch);
w1.start();//
w2.start();//
countDownLatch.await();// 等待所有工人完成工作
System.out.println("all work done at " + sdf.format(new Date()));
}
static class Worker extends Thread {
String workerName;
int workTime;
CountDownLatch latch;
public Worker(String workerName, int workTime, CountDownLatch latch) {
this.workerName = workerName;
this.workTime = workTime;
this.latch = latch;
}
@Override
public void run() {
System.out.println("Worker " + workerName + " do work begin at "
+ sdf.format(new Date()));
try {
Thread.sleep(workTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Worker " + workerName + " do work complete at "
+ sdf.format(new Date()));
latch.countDown();// 工人完成工作,計數(shù)器減一
}
}
}
|
|