【发布时间】:2020-05-31 21:49:03
【问题描述】:
我想实现一个交通信号灯(一个盒子)。我看到SO中有很多问题,但我觉得它们不是完整的代码。
以下是完整的来源。我使用lock 和condition 来决定哪个线程将实际运行。
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