CountDownLatch
概念
CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。
CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。可以解决当一个某线程任务需要依赖其他异步线程执行完后的结果,然后再执行这个线程的场景。
常用方法
//构造方法,创建一个值为count 的计数器。
CountDownLatch(int count);
//阻塞当前线程,将当前线程加入阻塞队列。
await();
//在timeout的时间之内阻塞当前线程,时间一过则当前线程可以执行,
await(long timeout, TimeUnit unit);
//对计数器进行递减1操作,当计数器递减至0时,当前线程会去唤醒阻塞队列里的所有线程。
countDown();
示例代码
public class CountDownLatchDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
CountDownLatch countDownLatch = new CountDownLatch(2);
executorService.submit(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始执行任务one");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() + " 任务one执行完毕");
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
});
executorService.submit(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始执行任务two");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " 任务two执行完毕");
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有线程执行完毕");
}
}
结果:
join()
概念
thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。
比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。
示例代码
public class Worker extends Thread{
private String name;
private long time;
public Worker(String name, long time) {
this.name = name;
this.time = time;
}
@Override
public void run() {
System.out.println(name + "任务开始");
try {
Thread.sleep(time);
System.out.println(name + "任务结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class JoinDemo {
public static void main(String[] args) throws InterruptedException {
Worker one = new Worker("one", 5000L);
Worker two = new Worker("two", 3000L);
Worker three = new Worker("three", 4000L);
one.start();
two.start();
one.join();
two.join();
System.out.println("任务one、two完成");
three.start();
}
}
结果: