正如问题所述,我正在尝试对四向交叉口进行非常非常简单的交通信号灯模拟。我的问题是,我正在使用两个不同的线程并尝试在两者之间来回反复使用wait并在for循环中通知。我在下面有一些伪代码。
public class Processor
{
public static int CarCounter = 1;
public void lightOneAndTwo() throws InterruptedException
{
synchronized(this)
{
for(int carsOne = 0; carsOne < 50; carsOne++)
{
//Light One---------------------------->
//Light Two---------------------------->
wait();
}
}
}
public void lightThreeAndFour() throws InterruptedException
{
Thread.sleep(1000);
synchronized(this)
{
for(int carsTwo = 0; carsTwo < 50; carsTwo++ )
{
//Light Three---------------------------->
notify();
}
}
}
}
但是当我调用notify时,它不会重新激活第一个线程。我做错了什么或者有更好的方法吗?
答案 0 :(得分:1)
你的程序有多个问题 - 没有条件变量,没有循环检查条件等。下面是一个可能的解决方案。我有四个班级:
MyLock - (锁定对象)
package com.test;
public class MyLock {
private volatile boolean condition;
public MyLock(boolean condition) {
this.condition = condition;
}
public boolean condition() {
return condition;
}
public void flipCondition() {
condition = !condition;
}
}
TrafficLightWorkerOne(交通工作者)
package com.test;
public class TrafficLightWorkerOne implements Runnable {
private int cars;
private MyLock lock;
public TrafficLightWorkerOne(MyLock lock, int cars) {
this.lock = lock;
this.cars = cars;
}
@Override
public void run() {
while (true) {
synchronized (lock) {
while (!lock.condition()) {
for (int carsOne = 0; carsOne < cars; carsOne++) {
System.out.println(Thread.currentThread().getName()
+ " car no : " + carsOne);
// Light One---------------------------->
// Light Two---------------------------->
}
lock.notifyAll();
lock.flipCondition();
}
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
TrafficLightWorkerTwo(另一名交通工作者)
package com.test;
public class TrafficLightWorkerTwo implements Runnable {
private int cars;
private MyLock lock;
public TrafficLightWorkerTwo(MyLock lock, int cars) {
this.lock = lock;
this.cars = cars;
}
@Override
public void run() {
while (true) {
synchronized (lock) {
try {
while (!lock.condition()) {
lock.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int carsOne = 0; carsOne < cars; carsOne++) {
System.out.println(Thread.currentThread().getName()
+ " car no : " + carsOne);
// Light One---------------------------->
// Light Two---------------------------->
}
lock.flipCondition();;
lock.notifyAll();
}
}
}
}
TrafficLightSimulator(主类)
package com.test;
public class TrafficLightSimulator {
public static void main(String[] args) {
boolean condition = false;
MyLock lock = new MyLock(condition);
Thread threadOne = new Thread(new TrafficLightWorkerOne(lock, 5), "One");
Thread threadTwo = new Thread(new TrafficLightWorkerTwo(lock, 4), "Two");
threadOne.start();
threadTwo.start();
}
}