0

我正在尝试使用 Java 中的多线程来实现交通信号。但是,我的代码似乎无法正常工作。我打算让每个灯在一个单独的线程中运行,并希望它们三个相互同步以模拟交通信号。你能否建议如何纠正这个问题。

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();
    }
}
4

2 回答 2

0

我想我可以解决如下:

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();
    }
}
于 2020-03-01T14:57:16.493 回答
0
package com.learn.online.question;

public class TrafficSignal  implements Runnable{

    public enum Signal
    {
        GREEN,ORANGE,RED;
    }


    private static volatile Signal previous=Signal.ORANGE;
    private Signal signal;
    private static Object lock=new Object();

    public TrafficSignal(Signal signal)
    {
        this.signal=signal;

    }


    public void  display() throws InterruptedException {
        synchronized (lock) {
            switch (signal) {
                case RED:
                    if (previous != Signal.ORANGE) {
                        lock.wait();
                    }
                    break;
                case GREEN:
                    if (previous != Signal.RED) {
                        lock.wait();
                    }
                    break;
                case ORANGE:
                    if (previous != Signal.GREEN) {
                        lock.wait();
                    }
                    break;
            }
            System.out.println("Colour : " + this.signal);
            Thread.sleep(5000);
            previous = signal;
            lock.notify();
        }
    }

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

    public static void main(String[] args) {
        new Thread(new TrafficSignal(Signal.GREEN)).start();
        new Thread(new TrafficSignal(Signal.RED)).start();
        new Thread(new TrafficSignal(Signal.ORANGE)).start();
    }
}
// Its similar to first one that was missing synchronized (lock) and lock
于 2021-05-22T07:20:49.390 回答