返回

Java 多线程 9:利用 Semaphore 实现信号灯

Android

引言

在并发的 Java 世界中,协调多个线程之间的访问至关重要。Semaphore(信号量)是一种强大的工具,它使我们能够控制并发访问受限资源,就像在现实世界中信号灯控制交通一样。在本文中,我们将深入探讨 Semaphore,并展示如何利用它来实现一个模拟现实生活中信号灯的 Java 程序。

1. Semaphore 的基本概念

Semaphore 是一个计数器,它允许我们限制可以同时访问特定资源的线程数。它提供了一种机制来确保一次只有一个线程可以访问临界区(即受保护的代码段),从而防止数据竞争和死锁。

Semaphore 有两个主要方法:

  • Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。
  • acquire():获取一个许可,如果当前没有许可可用,则线程将被阻塞,直到有许可可用。
  • release():释放一个许可,允许另一个线程获得许可并继续执行。

2. 使用 Semaphore 实现信号灯

交通信号灯是一种常见的并发控制示例。它协调从不同方向驶来的车辆,防止碰撞并确保交通顺畅。

我们可以使用 Semaphore 来模拟交通信号灯的行为。我们将创建一个包含两个信号灯的类,一个用于东西方向,另一个用于南北方向。

public class TrafficLight {

    private Semaphore eastWestSemaphore;
    private Semaphore northSouthSemaphore;

    public TrafficLight() {
        eastWestSemaphore = new Semaphore(1);
        northSouthSemaphore = new Semaphore(0);
    }

    public void eastWestGreen() {
        eastWestSemaphore.acquire();
        // 东西方向的车辆可以通行
        eastWestSemaphore.release();
    }

    public void northSouthGreen() {
        northSouthSemaphore.acquire();
        // 南北方向的车辆可以通行
        northSouthSemaphore.release();
    }
}

在我们的 TrafficLight 类中,eastWestSemaphorenorthSouthSemaphore 表示信号灯的许可。当东西方向的信号灯为绿灯时,eastWestSemaphore 具有一个许可,允许一辆车通过。当南北方向的信号灯为绿灯时,northSouthSemaphore 具有一个许可,允许另一辆车通过。

3. 模拟交通

为了模拟交通,我们将创建 Car 类,代表在信号灯前等待的车辆。每个 Car 对象将具有一个方向(东西或南北),并从 TrafficLight 对象获取许可:

public class Car implements Runnable {

    private TrafficLight trafficLight;
    private String direction;

    public Car(TrafficLight trafficLight, String direction) {
        this.trafficLight = trafficLight;
        this.direction = direction;
    }

    @Override
    public void run() {
        while (true) {
            if (direction.equals("east-west")) {
                trafficLight.eastWestGreen();
            } else {
                trafficLight.northSouthGreen();
            }
            // 车辆通过信号灯
            // ...
        }
    }
}

4. 运行模拟

为了运行模拟,我们将创建多个 Car 对象并启动它们:

public class Main {

    public static void main(String[] args) {
        TrafficLight trafficLight = new TrafficLight();

        Car car1 = new Car(trafficLight, "east-west");
        Car car2 = new Car(trafficLight, "north-south");
        Car car3 = new Car(trafficLight, "east-west");
        Car car4 = new Car(trafficLight, "north-south");

        Thread thread1 = new Thread(car1);
        Thread thread2 = new Thread(car2);
        Thread thread3 = new Thread(car3);
        Thread thread4 = new Thread(car4);

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
}

5. 结论

Semaphore 为我们提供了一种有效的方式来协调并发访问受限资源。通过模拟交通信号灯,我们展示了 Semaphore 如何用于解决现实世界中的并发控制问题。Semaphore 是 Java 多线程编程中的一个宝贵工具,有助于我们构建可靠且可扩展的并发应用程序。