javamultithreadingconcurrencytraffic-simulation

Traffic Signal Implementation using multithreading in Java


I am trying to implement traffic signal using multithreading in Java. However, my code doesn't seem to work correctly. I intend to have each light run in a separate thread and want all three of them to synchronize among themselves to simulate traffic signal. Can you please suggest how to rectify this.

public class TrafficSignal implements Runnable {
    public enum Color {RED, ORANGE, GREEN}

    private Color color;

    private static volatile Color previous = Color.ORANGE;

    public TrafficSignal(Color color) {
        this.color = color;
    }

    public synchronized void display() throws InterruptedException {
        switch (color) {
            case RED:
                while (previous != Color.ORANGE) wait();
                break;

            case ORANGE:
                while (previous != Color.GREEN) wait();
                break;

            case GREEN:
                while (previous != Color.RED) wait();
                break;
        }

        System.out.println(this.color);
        Thread.sleep(1000);
        previous = color;
        notifyAll();
    }

    @Override
    public void run() {
        while (true) {
            try {
                display();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new TrafficSignal(TrafficSignal.Color.GREEN)).start();
        new Thread(new TrafficSignal(TrafficSignal.Color.ORANGE)).start();
        new Thread(new TrafficSignal(TrafficSignal.Color.RED)).start();
    }
}

Solution

  • I think I'm able resolve it as below:

    import java.util.Arrays;
    import java.util.List;
    
    public class TrafficSignal implements Runnable {
        public enum Color {RED, ORANGE, GREEN}
        private List<Color> light = Arrays.asList(Color.GREEN, Color.ORANGE, Color.RED);
    
        private static volatile int counter = 0;
        private int i;
    
        private static final Object lock = new Object();
    
        public TrafficSignal(Color color) {
            this.i = light.indexOf(color);
        }
    
        @Override
        public void run() {
            try {
                synchronized (lock) {
                    while (true) {
                        while (counter % light.size() != i) lock.wait();
                        System.out.println(Thread.currentThread().getName() + " :: " + light.get(counter % light.size()));
                        counter++;
                        Thread.sleep(1000);
                        lock.notifyAll();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            new Thread(new TrafficSignal(TrafficSignal.Color.GREEN)).start();
            new Thread(new TrafficSignal(TrafficSignal.Color.ORANGE)).start();
            new Thread(new TrafficSignal(TrafficSignal.Color.RED)).start();
        }
    }