В настоящее время я пытаюсь разобраться в работе с многопоточностью и написать программу «Порт / Гавань», которая также содержит систему Ships and Delivering.Корабли загружают и доставляют контейнеры в порт, и если порт заполнен или пуст. Доставляющая система будет загружаться оттуда или доставлять новые контейнеры. Проблема в том, что я просто хочу контролировать доставку системы, используя await / signal, может кто-то помочь и посоветовать мне.Спасибо)
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();
}
}
в Корабле все в порядке, я хочу, чтобы при загрузке / доставке контейнеров и доставке поток работал бесконечно, доставка / загрузка в портовые методыкогда это необходимо, используя await ().