当前,我试图弄清楚使用多线程并编写程序“ Port / Harbor”,其中还包含Ships and Delivering系统。 船舶正在将集装箱装载并运送到港口,如果港口已满或空,则运送系统将从那里装载或运送新的集装箱。问题是我只想使用等待/信号来控制运送系统,有人可以帮忙并给我建议吗。谢谢)
public class DeliveryController {
private static final Logger LOGGER = LogManager.getLogger(DeliveryController.class);
private Port port;
private Condition isFull;
public DeliveryController(Port port){
this.port = port;
isFull = port.getLock().newCondition();
}
public void deliverToPort(Port port, Ship ship) {
port.getLock().lock();
try {
LOGGER.info(ship.getModel() + " delivering containers to port");
while (ship.getContainerCount() != 0) {
port.loadContainers(ship.getContainerCount());
ship.deliverContainers(ship.getContainerCount());
while (port.getContainerCount() >= Port.CAPACITY / 2 + 500)
try {
LOGGER.info("Port is full,waiting for a container service " + ship.getModel());
isFull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("Finished delivering to port " + ship.getModel());
} finally {
port.getLock().unlock();
}
}
public void loadFromPort(Port port, int containerAmount) {
port.getLock().lock();
try {
LOGGER.info("Getting containers from port");
while (port.getContainerCount() >= Delivery.MIN_CONTAINER_AMOUNT) {
port.unloadContainers(containerAmount);
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("Port is free,continue delivering");
isFull.signal();
} finally {
port.getLock().unlock();
}
}
}
public class LoadController {
private static final Logger LOGGER = LogManager.getLogger(LoadController.class);
private Port port;
private Condition isEmpty;
public LoadController(Port port) {
this.port = port;
isEmpty = port.getLock().newCondition();
}
public void loadFromPort(Port port, Ship ship, int containerCount) {
port.getLock().lock();
try {
while (ship.getContainerCount() <= ship.getCapacity()) {
port.unloadContainers(containerCount);
ship.loadContainers(containerCount);
while (port.getContainerCount() < Delivery.MIN_CONTAINER_AMOUNT) {
try {
LOGGER.info("Port is free,waiting for a container delivering " + ship.getModel());
isEmpty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
LOGGER.info("Finished loading to ship " + ship.getModel());
} finally {
port.getLock().unlock();
}
}
public void deliverToPort(Port port, int containerAmount) {
port.getLock().lock();
try {
LOGGER.info("Started Delivering containers to port");
while (port.getContainerCount() < Port.CAPACITY) {
port.loadContainers(containerAmount);
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info("Delivering to port finished");
isEmpty.signal();
} finally {
port.getLock().unlock();
}
}
}
public class Ship implements Runnable {
private static final Logger LOGGER = LogManager.getLogger(Ship.class);
private int capacity;
private String model;
private ServiceType serviceType;
private AtomicInteger containerCount = new AtomicInteger();
private Port port;
public Thread load, deliver;
public boolean running = false;
private Semaphore semaphore;
private LoadController loadController;
private static final int LOAD_CONTAINER_AMOUNT = 50;
private DeliveryController deliveryController;
public Ship(int containerCount, String model, ServiceType serviceType, int capacity, Port port,
LoadController loadController, DeliveryController deliveryController, Semaphore semaphore) {
this.capacity = capacity;
this.model = model;
this.serviceType = serviceType;
this.containerCount.set(containerCount);
this.port = port;
this.loadController = loadController;
this.deliveryController = deliveryController;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
LOGGER.info("Ship " + model + " came to the port");
if (serviceType.toString().equals("LOAD")) {
LOGGER.info("Ship " + model + " is loading");
load();
} else if (serviceType.toString().equals("DELIVERY")) {
LOGGER.info("Ship " + model + " is delivering");
deliver();
} else {
LOGGER.info("Ship " + model + " is delivering and loading");
deliver();
load();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOGGER.info(model + " finished and leaving the port");
semaphore.release();
}
private void load() {
load = new Thread(() -> {
loadController.loadFromPort(port, this, LOAD_CONTAINER_AMOUNT);
});
load.start();
}
private void deliver() {
deliver = new Thread(() -> {
deliveryController.deliverToPort(port, this);
});
deliver.start();
}
public class Delivery implements Runnable {
private Port port;
public final static int MIN_CONTAINER_AMOUNT = 250;
private final static int DELIVER_CONTAINER_COUNT = 200;
private LoadController loadController;
private DeliveryController deliveryController;
private Thread loadContainers, deliverContainers;
public Delivery(Port port, LoadController loadController, DeliveryController deliveryController) {
this.port = port;
this.loadController = loadController;
this.deliveryController = deliveryController;
}
@Override
public void run() {
}
private void loadContainers() {
loadContainers = new Thread(new Runnable() {
@Override
public void run() {
deliveryController.loadFromPort(port, DELIVER_CONTAINER_COUNT);
}
});
loadContainers.start();
}
private void deliverContainers() {
deliverContainers = new Thread(() -> loadController.deliverToPort(port, DELIVER_CONTAINER_COUNT));
deliverContainers.start();
}
}
在Ship中一切正常,我希望当我加载/交付容器并且Deliver线程将无限工作时,在必要时使用await()交付/加载以包含方法。