📜  同步控制计数器(1)

📅  最后修改于: 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()等待所有线程执行完毕,然后输出信息。