Java 多线程 9:利用 Semaphore 实现信号灯
2023-10-10 04:17:27
引言
在并发的 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
类中,eastWestSemaphore
和 northSouthSemaphore
表示信号灯的许可。当东西方向的信号灯为绿灯时,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 多线程编程中的一个宝贵工具,有助于我们构建可靠且可扩展的并发应用程序。