模拟交通信号灯(一个盒子)

问题描述 投票:0回答:1

我想实施一个交通信号灯(一个盒子)。我看到SO中有很多问题,但我觉得它们不是完整的代码。

以下为完整资料。我正在使用lockcondition来确定实际运行哪个线程。

TrafficSignalSimulationUsingLock.java

package com.example.practice.third;

import java.util.concurrent.locks.Condition;

import com.example.practice.third.custom.lock.TrafficLock;
import com.example.practice.third.threads.GreenColorLightThread;
import com.example.practice.third.threads.RedColorLightThread;
import com.example.practice.third.threads.YellowColorLightThread;

public class TrafficSignalSimulationUsingLock {

    public static void main(String[] args) throws InterruptedException {

        TrafficLock lock = new TrafficLock();

        Condition condition = lock.newCondition();

        Thread redThread = new Thread(new RedColorLightThread(lock, condition));
        Thread yellowThread = new Thread(new YellowColorLightThread(lock, condition));
        Thread greenThread = new Thread(new GreenColorLightThread(lock, condition));

        redThread.start();

        Thread.sleep(300);

        yellowThread.start();
        greenThread.start();

        redThread.join();
        yellowThread.join();
        greenThread.join();
    }
}

RedColorLightThread.java

package com.example.practice.third.threads;

import java.util.concurrent.locks.Condition;

import com.example.practice.third.custom.lock.TrafficLock;

public class RedColorLightThread implements Runnable {

    private TrafficLock trafficLock;
    private Condition condition;

    public RedColorLightThread(TrafficLock trafficLock, Condition condition) {
        this.trafficLock = trafficLock;
        this.condition = condition;
    }

    @Override
    public void run() {

        while (true) {
            try {
                trafficLock.lock();

                while (trafficLock.isYellow() && trafficLock.isGreen()) {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int i = 0; i < 5; i++) {
                    System.out.println("Red signal enabled");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                trafficLock.setYellow(true);
                trafficLock.setGreen(false);
                condition.signalAll();

            } finally {
                trafficLock.unlock();
            }
        }
    }
}

YellowColorLightThread.java

package com.example.practice.third.threads;

import java.util.concurrent.locks.Condition;

import com.example.practice.third.custom.lock.TrafficLock;

public class YellowColorLightThread implements Runnable {

    private TrafficLock trafficLock;
    private Condition condition;

    public YellowColorLightThread(TrafficLock trafficLock, Condition condition) {
        this.trafficLock = trafficLock;
        this.condition = condition;
    }

    @Override
    public void run() {

        while (true) {
            try {
                trafficLock.lock();

                while (trafficLock.isRed() && trafficLock.isGreen()) {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int i = 0; i < 3; i++) {
                    System.out.println("Yellow signal enabled");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                trafficLock.setRed(false);
                trafficLock.setGreen(true);
                condition.signalAll();

            } finally {
                trafficLock.unlock();
            }
        }
    }
}

GreenColorLightThread.java

package com.example.practice.third.threads;

import java.util.concurrent.locks.Condition;

import com.example.practice.third.custom.lock.TrafficLock;

public class GreenColorLightThread implements Runnable {

    private TrafficLock trafficLock;
    private Condition condition;

    public GreenColorLightThread(TrafficLock trafficLock, Condition condition) {
        this.trafficLock = trafficLock;
        this.condition = condition;
    }

    @Override
    public void run() {

        while (true) {
            try {
                trafficLock.lock();

                while (trafficLock.isRed() && trafficLock.isYellow()) {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int i = 0; i < 5; i++) {
                    System.out.println("Green signal enabled");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                trafficLock.setRed(true);
                trafficLock.setYellow(false);
                condition.signalAll();

            } finally {
                trafficLock.unlock();
            }
        }
    }
}

TrafficLock.java

package com.example.practice.third.custom.lock;

import java.util.concurrent.locks.ReentrantLock;

public class TrafficLock extends ReentrantLock {

    /**
     * 
     */
    private static final long serialVersionUID = 7311233763066170670L;

    private boolean red = true;
    private boolean yellow = false;
    private boolean green = false;

    public TrafficLock() {
        super(true);
    }

    public boolean isRed() {
        return red;
    }

    public void setRed(boolean red) {
        this.red = red;
    }

    public boolean isYellow() {
        return yellow;
    }

    public void setYellow(boolean yellow) {
        this.yellow = yellow;
    }

    public boolean isGreen() {
        return green;
    }

    public void setGreen(boolean green) {
        this.green = green;
    }
}

以下是示例输出:

Red signal enabled
Red signal enabled
Red signal enabled
Red signal enabled
Red signal enabled
Yellow signal enabled
Yellow signal enabled
Yellow signal enabled
Green signal enabled
Green signal enabled
Green signal enabled
Green signal enabled
Green signal enabled
Red signal enabled
Red signal enabled

这是实现的正确方法(请忽略空格,时间复杂度。]

尽管此程序可以达到我期望的结果,但我有一个小疑问:

在每个“彩色线程”(例如“ RedColorLightThread”)中,线程首先设置下一个所需的状态,然后设置condition.signalAll(),然后在finally block中释放锁定。

我的疑问是,当例如“红色线程”还没有释放锁定时,其他线程不会立即唤醒吗?

java multithreading condition-variable reentrantlock
1个回答
0
投票

锁一次只能由一个线程持有。当您向其他线程发出信号时,您是在告诉他们它们可以唤醒并尝试获取该锁,但是它们只有在获得该锁时才会继续前进。只有在其他线程将其解锁时才会发生这种情况。之后,只有等待的线程将唤醒并锁定该锁,而其他线程则保持等待。

© www.soinside.com 2019 - 2024. All rights reserved.