最近写Java多线程的一些功能,任务A、B执行完成以后任务C才能执行,使用主线程必须等待A、B执行完成后,执行任务C;
查询到 实现 Calllable 接口, 调用 Future对象执行状态,判断任务是否完成 -
参考文档:Java多线程Future、FutureTask的使用
但是这个CountDownLatch 似乎更好用哦~
引言
CountDownLatch是jdk1.5开始concurrent包里提供的,并发编程工具类。
这个类能够使一个线程等待其他线程完成各自的工作后再执行,可用于多线程的并发执行。
例如,应用程序的主线程希望在多个网络请求线程并发执行完后,刷新页面,避免串行请求导致网络请求耗时长。
CountDownLatch的使用
CountDownLatch的主要使用步骤是
1、初始化,指定线程个数,CountDownLatch latch = new CountDownLatch(3);
参数4代表线程的总数
2、每个线程执行后执行latch.countDown();,代表一个线程执行完成,待完成的线程数减1。
3、在线程添加latch.await();,阻塞该线程,等待其他子线程完成。
例子:
package com.example.zzh.myapplication;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
// Let us create task that is going to
// wait for four threads before it starts
CountDownLatch latch = new CountDownLatch(3);
long start = System.currentTimeMillis();
// Let us create four worker
// threads and start them.
WorkerThread first = new WorkerThread(1000, latch, "worker-1");
WorkerThread second = new WorkerThread(2000, latch, "worker-2");
WorkerThread third = new WorkerThread(3000, latch, "worker-3");
first.start();
second.start();
third.start();
// The main task waits for four threads
latch.await();
// Main thread has started
System.out.println(Thread.currentThread().getName() + " has finished. Spend Time = " + (System.currentTimeMillis() - start));
}
// A class to represent threads for which
// the main thread waits.
static class WorkerThread extends Thread {
private int delay;
private CountDownLatch latch;
public WorkerThread(int delay, CountDownLatch latch, String name) {
super(name);
this.delay = delay;
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(delay);
latch.countDown();
System.out.println(Thread.currentThread().getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果
worker-1 finished
worker-2 finished
worker-3 finished
main has finished. Spend Time = 3006
扩展内容
1、CountDownLatch的优缺点
优点:
对使用者而言,你只需要传入一个int型变量控制任务数量即可,至于同步队列的出队入队维护,state变量值的维护对使用者都是透明的,使用方便。
缺点:
CountDownLatch设置了state后就不能更改,也不能循环使用。
2、CountDownLatch的超时处理
如果线程等待超过一定时间,可以取消阻塞被唤醒,那么可以通过设置await的参数
//等待超过2s,自动被唤醒
latch.await(2000, TimeUnit.MILLISECONDS);
注:原文有源码解析哟~