【问题标题】:Simulating traffic signal (a single box)模拟交通信号(单框)
【发布时间】:2020-05-31 21:49:03
【问题描述】:

我想实现一个交通信号灯(一个盒子)。我看到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】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 2015-05-12
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 2013-11-23
      • 1970-01-01
      相关资源
      最近更新 更多