diff --git a/main/src/main/java/sd/IntersectionProcess.java b/main/src/main/java/sd/IntersectionProcess.java index ee95058..57c658f 100644 --- a/main/src/main/java/sd/IntersectionProcess.java +++ b/main/src/main/java/sd/IntersectionProcess.java @@ -171,6 +171,29 @@ public class IntersectionProcess { System.out.println(" Routing configured."); } + /** + * Requests permission for a traffic light to turn green. + * Blocks until permission is granted (no other light is green). + * + * @param direction The direction requesting green light + */ + public void requestGreenLight(String direction) { + trafficCoordinationLock.lock(); + currentGreenDirection = direction; + } + + /** + * Releases the green light permission, allowing another light to turn green. + * + * @param direction The direction releasing green light + */ + public void releaseGreenLight(String direction) { + if (direction.equals(currentGreenDirection)) { + currentGreenDirection = null; + trafficCoordinationLock.unlock(); + } + } + /** * Starts all traffic light threads. */ diff --git a/main/src/main/java/sd/engine/TrafficLightThread.java b/main/src/main/java/sd/engine/TrafficLightThread.java index f3951df..1f1c197 100644 --- a/main/src/main/java/sd/engine/TrafficLightThread.java +++ b/main/src/main/java/sd/engine/TrafficLightThread.java @@ -29,7 +29,6 @@ public class TrafficLightThread implements Runnable { @Override public void run() { - // Capture the current thread reference this.currentThread = Thread.currentThread(); this.running = true; System.out.println("[" + light.getId() + "] Traffic light thread started."); @@ -37,29 +36,37 @@ public class TrafficLightThread implements Runnable { try { while (running && !Thread.currentThread().isInterrupted()) { - // --- GREEN Phase --- - light.changeState(TrafficLightState.GREEN); - System.out.println("[" + light.getId() + "] State: GREEN"); + // Request permission to turn green (blocks until granted) + process.requestGreenLight(light.getDirection()); - processGreenLightQueue(); - - if (!running || Thread.currentThread().isInterrupted()) break; - - // Wait for green duration - Thread.sleep((long) (light.getGreenTime() * 1000)); - - if (!running || Thread.currentThread().isInterrupted()) break; + try { + // --- GREEN Phase --- + light.changeState(TrafficLightState.GREEN); + System.out.println("[" + light.getId() + "] State: GREEN"); + + processGreenLightQueue(); + + if (!running || Thread.currentThread().isInterrupted()) break; + + // Wait for green duration + Thread.sleep((long) (light.getGreenTime() * 1000)); + + if (!running || Thread.currentThread().isInterrupted()) break; - // --- RED Phase --- - light.changeState(TrafficLightState.RED); - System.out.println("[" + light.getId() + "] State: RED"); + // --- RED Phase --- + light.changeState(TrafficLightState.RED); + System.out.println("[" + light.getId() + "] State: RED"); + + } finally { + // Always release the green light permission + process.releaseGreenLight(light.getDirection()); + } // Wait for red duration Thread.sleep((long) (light.getRedTime() * 1000)); } } catch (InterruptedException e) { System.out.println("[" + light.getId() + "] Traffic light thread interrupted."); - // Restore interrupt status Thread.currentThread().interrupt(); } finally { this.running = false; diff --git a/main/src/test/java/sd/TrafficLightCoordinationTest.java b/main/src/test/java/sd/TrafficLightCoordinationTest.java index 1fe51a3..347864d 100644 --- a/main/src/test/java/sd/TrafficLightCoordinationTest.java +++ b/main/src/test/java/sd/TrafficLightCoordinationTest.java @@ -1,18 +1,18 @@ package sd; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; - -import sd.model.TrafficLight; -import sd.model.TrafficLightState; - import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import sd.model.TrafficLight; +import sd.model.TrafficLightState; /** * Test class to verify traffic light coordination within an intersection. @@ -108,7 +108,7 @@ public class TrafficLightCoordinationTest { assertTrue(maxGreenSimultaneously.get() <= 1, "At most ONE light should be GREEN at any time. Found: " + maxGreenSimultaneously.get()); - System.out.println("\n✅ Traffic light coordination working correctly!"); + System.out.println("\nTraffic light coordination working correctly!"); } /**