Добрый день. Уже несколько дней пытаюсь разобраться, но не получается.
Суть задания: реализую магазин автомобилей, где покупатель приходит в магазин авто и ждет пока завод выпустит авто, чтобы на нем уехать. Пока честную очередь не хочу реализовывать, но суть вопроса будет не в этом.
Ещё пару условий для понимания:
- Каждый ключевой этап должен сопровождаться выводом в консоль текущего статуса, например: Производитель Toyota выпустил 1 автомобиль
- Должно быть несколько потоков-покупателей, которые будут желать несколько раз купить машину. Производитель выпускает по 1 машине. Программу можно завершать после продажи 10 машин
Проблема: всё работает, кроме главного, где покупатель ждет в очереди, а потом покупает машину. Либо, например, покупатель # 2 доходит до метода waitForCar , где пишется “There are NO car left” , но в итоге покупатель не покупает и остается без покупки… Либо покупатель (как сейчас в редакции кода) не доходит до метода waitForCar … что не реализует саму идею ожидания.
Помогите, пожалуйста, что не так в классе ShowRoom… Скорее всего надо что-то сделать с методом waitForCar и как-то его синхронизировать (всяко разно пробовал, но не получается)…
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static List<Thread> mThreadList;
public static void main(String[] args) throws IOException {
Manufactured manufactured = new Manufactured("Toyota");
mThreadList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ShowRoom showRoom = new ShowRoom(manufactured);
mThreadList.add(new Thread(showRoom, "Client #" + (i + 1)));
mThreadList.get(i).start();
new Thread(() -> manufactured.sendToShop(showRoom), manufactured.toString()).start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
import java.util.ArrayList;
import java.util.List;
class Manufactured {
private String name;
public Manufactured(String name) {
this.name = name;
}
public synchronized void sendToShop(ShowRoom showRoom) {
try {
System.out.format("Factory has been created %s 1 car!\n", name);
Thread.sleep(1000);
showRoom.addCar(new CreateCar(this));
System.out.format("There are %s %s car(s) left\n", showRoom.getNoOfCars(),name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class ShowRoom implements Runnable {
Manufactured manufactured;
private static final List<CreateCar> cars = new ArrayList<>();
public ShowRoom(Manufactured manufactured) {
this.manufactured = manufactured;
}
public void run() {
enterToShowRoom(manufactured);
if (CarsGreaterThanZero()) {
getInTheCarAndDrive();
} else if (CarsEqualToZero()) {
// waitForCar();
try {
while (cars.isEmpty()) {
System.out.println("There are NO car left");
manufactured.wait();
}
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getInTheCarAndDrive();
}
}
public boolean CarsGreaterThanZero() {
synchronized (manufactured) {
if (getNoOfCars() > 0) {
return true;
} else {
return false;
}
}
}
public boolean CarsEqualToZero() {
synchronized (manufactured) {
if (getNoOfCars() == 0) {
return true;
} else {
return false;
}
}
}
void waitForCar() {
synchronized (manufactured) {
try {
while (cars.isEmpty()) {
System.out.println("There are NO car left");
manufactured.wait();
}
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void getInTheCarAndDrive() {
synchronized (manufactured) {
removeNoOfCars();
System.out.println(Thread.currentThread().getName()
+ " has bought, " + getNoOfCars()
+ " available");
}
Random numGen = new Random();
int r = numGen.nextInt(1000);
try {
Thread.sleep(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void addCar(CreateCar createCar) {
cars.add(createCar);
notify();
}
public int getNoOfCars() {
return cars.size();
}
public void removeNoOfCars() {
int index = cars.size() - 1;
cars.remove(index);
}
public synchronized void enterToShowRoom(Manufactured manufactured){
System.out.println(Thread.currentThread().getName()+" entered to showroom");
}
}
public class CreateCar {
private final Manufactured manufactured;
public CreateCar(Manufactured manufactured) {
this.manufactured = manufactured;
}
}