请帮帮我一点。我在使用Exchanger时遇到问题。当乘客试图改变公共汽车时,程序阻塞。任务:如果两辆公共汽车在同一车站,乘客可以换乘公共汽车。
班级Bus
:
public class Bus implements Runnable {
private Lock lock = new ReentrantLock();
private Exchanger<Passengers> exchanger;
private Passengers passengers;
private ArrayList<BusStation> busStations;
private int number;
private BeforeState beforeState = new BeforeState();
private AfterState afterState = new AfterState();
public Bus(ArrayList busStations, int number, Passengers passengers, Exchanger<Passengers> exchanger) {
this.busStations = busStations;
this.number = number;
this.passengers = passengers;
this.exchanger = exchanger;
}
public void addExchanger(Exchanger exchanger) {
this.exchanger = exchanger;
}
public Exchanger getExchanger() {
return exchanger;
}
public Bus(ArrayList busStations) {
this.busStations = busStations;
}
public void run() {
for (int i = 0; i < busStations.size(); i++) {
beforeState.doAction(this, busStations.get(i));
busStations.get(i).addBus(this);
afterState.doAction(this, busStations.get(i));
busStations.get(i).getSemaphore().release();
}
}
public int getNumber() {
return number;
}
public void setPassengers(Passengers passengers) {
lock.lock();
if (passengers.getQuantity() < 0)
passengers = new Passengers(0);
try {
this.passengers = passengers;
} finally {
lock.unlock();
}
}
public Passengers getPassengers() {
lock.lock();
try {
return passengers;
} finally {
lock.unlock();
}
}
}
班级BusStation
:
public class BusStation {
private final static Logger logger = Logger.getLogger(BusStation.class);
private String name;
private final int busLimit = 2;
private Semaphore semaphore = new Semaphore(busLimit);
public BusStation(String name) {
this.name = name;
}
public String getName(){
return name;
}
public void addBus(Bus bus){
try {
semaphore.acquire();
} catch (InterruptedException e) {
logger.error("Semaphore error", e);
}
new InState().doAction(bus, this);
}
public Semaphore getSemaphore(){
return semaphore;
}
}
控制公交车站活动的班级:
public class InState implements IState {
private final static Logger logger = Logger.getLogger(InState.class);
@Override
public void doAction(Bus bus, BusStation busStation) {
logger.info("Bus number " + bus.getNumber() + " is on the station " + busStation.getName());
Random rand = new Random();
if (busStation.getSemaphore().availablePermits() == 0) {
if (rand.nextInt(10) > 5) {
try {
Passengers tmpPassengers = bus.getPassengers(); //
tmpPassengers = (Passengers) bus.getExchanger().exchange(bus.getPassengers()); // Here programm`s blocking
// bus.setPassengers(tmpPassengers); //
} catch (InterruptedException e) {
logger.error("Exchanger mistake", e);
}
}
else
bus.setPassengers(new Passengers(bus.getPassengers().getQuantity() - rand.nextInt(10)));
}
}
public String toString() {
return "In state";
}
}