diff --git a/src/MainClass.java b/src/MainClass.java index fe5cd6a..0485389 100644 --- a/src/MainClass.java +++ b/src/MainClass.java @@ -3,19 +3,32 @@ import race.Road; import race.Tunnel; +import java.util.concurrent.CountDownLatch; + public class MainClass { public static final int CARS_COUNT = 4; - public static void main(String[] args) { + + public static CountDownLatch carsReadiness = new CountDownLatch(CARS_COUNT); + public static CountDownLatch notFinishedCars = new CountDownLatch(CARS_COUNT); + + public static void main(String[] args) throws InterruptedException { System.out.println("ВАЖНОЕ ОБЪЯВЛЕНИЕ >>> Подготовка!!!"); - Race race = new Race(new Road(60), new Tunnel(), new Road(40)); + + Race race = new Race(new Road(60), new Tunnel(CARS_COUNT/2), new Road(40)); Car[] cars = new Car[CARS_COUNT]; + for (int i = 0; i < cars.length; i++) { - cars[i] = new Car(race, 20 + (int) (Math.random() * 10)); + cars[i] = new Car(race, 20 + (int) (Math.random() * 10), carsReadiness, notFinishedCars); } + for (int i = 0; i < cars.length; i++) { new Thread(cars[i]).start(); } + + carsReadiness.await(); + System.out.println("ВАЖНОЕ ОБЪЯВЛЕНИЕ >>> Гонка началась!!!"); + notFinishedCars.await(); System.out.println("ВАЖНОЕ ОБЪЯВЛЕНИЕ >>> Гонка закончилась!!!"); } } diff --git a/src/race/Car.java b/src/race/Car.java index 02b44d6..9102c23 100644 --- a/src/race/Car.java +++ b/src/race/Car.java @@ -1,6 +1,6 @@ package race; -import java.security.cert.Extension; +import java.util.concurrent.CountDownLatch; public class Car implements Runnable { private static int CARS_COUNT; @@ -8,10 +8,14 @@ public class Car implements Runnable { CARS_COUNT = 0; } + private CountDownLatch carsReadiness; + private CountDownLatch notFinishedCars; + private Race race; private int speed; private String name; + public String getName() { return name; } @@ -20,10 +24,14 @@ public int getSpeed() { return speed; } - public Car(Race race, int speed) { + public Car(Race race, int speed, CountDownLatch carsReadiness, CountDownLatch notFinishedCars) { this.race = race; this.speed = speed; + this.carsReadiness = carsReadiness; + this.notFinishedCars = notFinishedCars; + CARS_COUNT++; + this.name = "Участник #" + CARS_COUNT; } @@ -33,11 +41,17 @@ public void run() { System.out.println(this.name + " готовится"); Thread.sleep(500 + (int)(Math.random() * 800)); System.out.println(this.name + " готов"); + + carsReadiness.countDown(); + carsReadiness.await(); } catch (Exception e) { e.printStackTrace(); } for (int i = 0; i < race.getStages().size(); i++) { race.getStages().get(i).go(this); } + + race.finish(this); + notFinishedCars.countDown(); } } diff --git a/src/race/Race.java b/src/race/Race.java index 9de4b2b..1b68a2a 100644 --- a/src/race/Race.java +++ b/src/race/Race.java @@ -5,10 +5,21 @@ public class Race { private ArrayList stages; + private int finished = 0; public ArrayList getStages() { return stages; } public Race(Stage... stages) { this.stages = new ArrayList<>(Arrays.asList(stages)); } + + public synchronized void finish(Car car) { + finished++; + + if (finished == 1) { + System.out.println(car.getName() + " - WIN"); + } else { + System.out.println(car.getName() + " закончил гонку"); + } + } } diff --git a/src/race/Tunnel.java b/src/race/Tunnel.java index 3539fe5..f070489 100644 --- a/src/race/Tunnel.java +++ b/src/race/Tunnel.java @@ -1,9 +1,14 @@ package race; +import java.util.concurrent.Semaphore; + public class Tunnel extends Stage { - public Tunnel() { + private Semaphore sph; + + public Tunnel(int limit) { this.length = 80; this.description = "Тоннель " + length + " метров"; + this.sph = new Semaphore(limit); } @Override @@ -11,12 +16,16 @@ public void go(Car c) { try { try { System.out.println(c.getName() + " готовится к этапу(ждет): " + description); + sph.acquire(); System.out.println(c.getName() + " начал этап: " + description); + Thread.sleep(length / c.getSpeed() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println(c.getName() + " закончил этап: " + description); + + sph.release(); } } catch (Exception e) { e.printStackTrace();