当多个线程并发执行时,可能会出现资源争抢、数据不一致等问题。因此,Java 提供了一些同步工具来帮助我们实现线程并发控制。其中,CountDownLatch 是一个非常实用的同步工具,它可以使线程等待其他线程执行完成再继续执行。
CountDownLatch 的概述
CountDownLatch 是 Java.util.concurrent 包下的一个同步工具,它主要用于线程之间的协调。它可以让某个线程等待其他线程完成后再继续执行。
CountDownLatch 的工作原理很简单:它有一个计数器,当计数器的值变为 0 时,所有等待者(调用 CountDownLatch.await() 的线程)开始执行。而 CountDownLatch.countDown() 方法可以让计数器的值减 1。
CountDownLatch 的使用示例
示例1 让多个线程按顺序执行
假设有 3 个线程 a、b、c,希望它们按顺序执行,即先执行 a,然后 b,最后 c。可以使用 CountDownLatch 来实现。
public class Demo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(2); // 初始化计数器为2
Thread a = new Thread(() -> {
System.out.println("a");
latch.countDown(); // 计数器减1
});
Thread b = new Thread(() -> {
try {
latch.await(); // 等待计数器变为0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("b");
latch.countDown();
});
Thread c = new Thread(() -> {
try {
latch.await(); // 等待计数器变为0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("c");
});
a.start();
b.start();
c.start();
a.join();
b.join();
c.join();
}
}
在上面的示例中,我们初始化了一个计数器为 2 的 CountDownLatch 对象 latch。当线程 a 执行完后,调用 latch.countDown() 方法,计数器的值变为 1;然后线程 b 调用 await() 方法等待计数器变为 0,即等待线程 a 执行完;当线程 a 执行完后,调用一次 latch.countDown() 方法,其中的 count 就为 1,然后线程 b 再次调用 await() 方法等待计数器变为 0;同理,当线程 b 执行完后,调用一次 latch.countDown() 方法,计数器的值变为 0,线程 c 被唤醒,执行完毕。
示例2 计算多线程执行时间
下面的示例演示了如何计算多线程的执行时间。首先,定义一个 CountDownLatch 对象,让主线程在等待所有子线程执行完成后再统计时间。然后,定义若干个线程,在每个线程中执行一定时间的任务。在每个线程的任务执行完成后,调用 CountDownLatch.countDown() 方法,使计数器值减 1。当计数器值为 0 时,主线程被唤醒,统计时间。
public class Test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch doneLatch = new CountDownLatch(5); // 5个线程完成
long start = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
Thread.sleep(new Random().nextInt(3000)); // 模拟不同的线程执行时间
System.out.println(Thread.currentThread().getName() + " 执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
doneLatch.countDown(); // 任务完成,计数器减 1
}
}, "Thread-" + i).start();
}
doneLatch.await(); // 等待所有线程执行完成
long end = System.currentTimeMillis();
System.out.println("所有线程执行时间:" + (end - start) + " 毫秒");
}
}
在上面的示例中,我们创建了 5 个线程,每个线程执行时间随机(3000 毫秒以内),完成后调用 CountDownLatch.countDown() 方法。主线程等待所有线程执行完后统计时间,并输出结果。
结论
CountDownLatch 是一个非常实用的同步工具,可以帮助我们实现线程之间的协调。在多线程编程中,我们可以使用它来使某个线程等待其他线程执行完毕、按顺序执行多个线程、统计多个线程的执行时间等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java线程并发控制同步工具CountDownLatch - Python技术站