📅  最后修改于: 2023-12-03 15:07:28.360000             🧑  作者: Mango
同步控制计数器是一种常用的同步机制,通常用于多线程程序中,用于协调多个线程之间的操作。它可以用来确保一组线程都已经完成了特定的操作,然后再允许其他线程执行。
同步控制计数器通常包含两个关键元素:计数器和等待队列。
这个计数器的初始值是0,每执行一次操作时,计数器加1。当所有线程都执行完毕时,计数器的值等于线程总数,此时就可以通知所有正在等待的线程继续执行。
在Java语言中,可以使用CountDownLatch类来实现同步控制计数器。该类提供了下面这些方法:
public CountDownLatch(int count)
:构造一个计数器,初始值为count。public void await() throws InterruptedException
:等待计数器的值为0,被唤醒后继续执行。public boolean await(long timeout, TimeUnit unit) throws InterruptedException
:在指定的时间内等待计数器的值为0,超时则继续执行。public void countDown()
:将计数器的值减1。下面是一个使用CountDownLatch实现同步控制计数器的简单示例:
import java.util.concurrent.CountDownLatch;
public class SynchronizedCounter {
public static void main(String[] args) throws InterruptedException {
int nThreads = 5;
CountDownLatch doneSignal = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; ++i) {
new Thread(new Worker(i, doneSignal)).start();
}
doneSignal.await(); // 等待所有线程执行完毕
System.out.println("所有线程都已执行完毕!");
}
private static class Worker implements Runnable {
private final int id;
private final CountDownLatch doneSignal;
public Worker(int id, CountDownLatch doneSignal) {
this.id = id;
this.doneSignal = doneSignal;
}
public void run() {
try {
System.out.println("线程 #" + id + " 正在执行...");
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
}
doneSignal.countDown(); // 计数器减1
System.out.println("线程 #" + id + " 已经执行完毕!");
}
}
}
输出:
线程 #0 正在执行...
线程 #1 正在执行...
线程 #3 正在执行...
线程 #2 正在执行...
线程 #4 正在执行...
线程 #2 已经执行完毕!
线程 #4 已经执行完毕!
线程 #0 已经执行完毕!
线程 #1 已经执行完毕!
线程 #3 已经执行完毕!
所有线程都已执行完毕!
在这个示例中,启动了5个线程,每个线程执行一个模拟的耗时操作,完成后调用doneSignal.countDown()将计数器的值减1。在主线程中调用doneSignal.await()等待所有线程执行完毕,然后输出信息。