我已经写出了我的代码,标明北向和南向的汽车穿过一条车道桥,但我在计算方面遇到了一些麻烦。
它应该是这样的:汽车正在等待,然后可能是几辆,每次都有一个交叉,每次都在增加。相反,它每次重复相同的三个数字。
我应该以不同的方式声明我的计数,还是我不正确地增加它?我尝试了很多不同的方法,但却找不到真正的问题。
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SingleLaneBridge {
public static void main(String[] args) {
final Bridge bridge = new Bridge();
Thread th1 = new Thread( new Runnable() {
@Override
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread th2 = new Thread( new Runnable() {
@Override
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
th1.start();
th2.start();
}
}
class Bridge {
private final Semaphore semaphore;
public Bridge() {
semaphore = new Semaphore(1);
}
public void crossBridge(Car car) {
try {
System.out.printf("Car %s is trying to cross the bridge. \n",car.count++);
semaphore.acquire();
System.out.printf("Car %s is crossing the bridge. \n",car.count++);
Thread.sleep(5000);
} catch(InterruptedException iex) {
iex.printStackTrace();
} finally {
System.out.printf(" Car %s has crossed the bridge. \n",car.count++);
semaphore.release();
}
}
}
class Car implements Runnable {
int count = 0;
private String name;
private Bridge bridge;
public Car(Bridge bridge) {
this.bridge = bridge;
}
public void run() {
bridge.crossBridge(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
答案 0 :(得分:1)
它一次又一次地重复这三个数字的原因是,每次都重新创建Car实例并将计数初始化为0.
为了解决这个问题,请按以下方式定义Car类,以获取原子计数,因为此处涉及多个线程(汽车),
class Car implements Runnable {
private static AtomicInteger globalCarID = new AtomicInteger(0);
int count;
...
public Car(Bridge bridge) {
this.bridge = bridge;
count = globalCarID.incrementAndGet();
}
}
并修改crossBridge()方法中的System.out.printf以不增加计数,
以下是可能提供您想要的完整代码,
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class SingleLaneBridge {
public static void main(String[] args) {
final Bridge bridge = new Bridge();
Thread th1 = new Thread( new Runnable() {
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
Thread th2 = new Thread( new Runnable() {
public void run() {
while(true) {
Car car = new Car(bridge);
Thread th = new Thread(car);
th.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
th1.start();
th2.start();
}
}
class Bridge {
private final Semaphore semaphore;
public Bridge() {
semaphore = new Semaphore(1);
}
public void crossBridge(Car car) {
try {
System.out.printf("Car %s is trying to cross the bridge. \n",car.count);
semaphore.acquire();
System.out.printf("Car %s is crossing the bridge. \n",car.count);
Thread.sleep(500);
} catch(InterruptedException iex) {
iex.printStackTrace();
} finally {
System.out.printf(" Car %s has crossed the bridge. \n",car.count);
semaphore.release();
}
}
}
class Car implements Runnable {
private static AtomicInteger globalCarID = new AtomicInteger(0);
int count;
private String name;
private Bridge bridge;
public Car(Bridge bridge) {
this.bridge = bridge;
count = globalCarID.incrementAndGet();
}
public void run() {
bridge.crossBridge(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}