diff --git a/lesson05/.idea/.gitignore b/lesson05/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/lesson05/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/lesson05/.idea/description.html b/lesson05/.idea/description.html new file mode 100644 index 0000000..db5f129 --- /dev/null +++ b/lesson05/.idea/description.html @@ -0,0 +1 @@ +Simple Java application that includes a class with main() method \ No newline at end of file diff --git a/lesson05/.idea/encodings.xml b/lesson05/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/lesson05/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lesson05/.idea/misc.xml b/lesson05/.idea/misc.xml new file mode 100644 index 0000000..adbdd33 --- /dev/null +++ b/lesson05/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/lesson05/.idea/modules.xml b/lesson05/.idea/modules.xml new file mode 100644 index 0000000..311dbd2 --- /dev/null +++ b/lesson05/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/lesson05/.idea/project-template.xml b/lesson05/.idea/project-template.xml new file mode 100644 index 0000000..1f08b88 --- /dev/null +++ b/lesson05/.idea/project-template.xml @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/lesson05/.idea/vcs.xml b/lesson05/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/lesson05/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lesson05/lesson05.iml b/lesson05/lesson05.iml new file mode 100644 index 0000000..d5c0743 --- /dev/null +++ b/lesson05/lesson05.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lesson05/out/production/lesson05/Geekbrains/Car.class b/lesson05/out/production/lesson05/Geekbrains/Car.class new file mode 100644 index 0000000..0305425 Binary files /dev/null and b/lesson05/out/production/lesson05/Geekbrains/Car.class differ diff --git a/lesson05/out/production/lesson05/Geekbrains/Main.class b/lesson05/out/production/lesson05/Geekbrains/Main.class new file mode 100644 index 0000000..f8adbfe Binary files /dev/null and b/lesson05/out/production/lesson05/Geekbrains/Main.class differ diff --git a/lesson05/out/production/lesson05/Geekbrains/Race.class b/lesson05/out/production/lesson05/Geekbrains/Race.class new file mode 100644 index 0000000..4469daa Binary files /dev/null and b/lesson05/out/production/lesson05/Geekbrains/Race.class differ diff --git a/lesson05/out/production/lesson05/Geekbrains/Road.class b/lesson05/out/production/lesson05/Geekbrains/Road.class new file mode 100644 index 0000000..2c0aa56 Binary files /dev/null and b/lesson05/out/production/lesson05/Geekbrains/Road.class differ diff --git a/lesson05/out/production/lesson05/Geekbrains/Stage.class b/lesson05/out/production/lesson05/Geekbrains/Stage.class new file mode 100644 index 0000000..f3bbd8a Binary files /dev/null and b/lesson05/out/production/lesson05/Geekbrains/Stage.class differ diff --git a/lesson05/out/production/lesson05/Geekbrains/Tunnel.class b/lesson05/out/production/lesson05/Geekbrains/Tunnel.class new file mode 100644 index 0000000..5bdb667 Binary files /dev/null and b/lesson05/out/production/lesson05/Geekbrains/Tunnel.class differ diff --git a/lesson05/src/Geekbrains/Main.java b/lesson05/src/Geekbrains/Main.java new file mode 100644 index 0000000..ce8abdd --- /dev/null +++ b/lesson05/src/Geekbrains/Main.java @@ -0,0 +1,193 @@ +package Geekbrains; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.concurrent.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class Main { + private static int CARS_COUNT = 4; + private static Lock lock =new ReentrantLock(); + + public static void main(String[] args) throws BrokenBarrierException, InterruptedException { + // Все участники должны стартовать одновременно, несмотря на разное время подготовки. == CyclicBarrier + // + // В тоннель не может одновременно заехать больше половины участников (условность). == Semaphore + //Попробуйте все это синхронизировать. + //Первый участник, пересекший финишную черту, объявляется победителем (в момент пересечения этой самой черты). == ? + //Победитель должен быть только один (ситуация с 0 или 2+ победителями недопустима). == ? + //Когда все завершат гонку, нужно выдать объявление об окончании. == ? + //Можно корректировать классы (в том числе конструктор машин) и добавлять объекты классов из пакета java.util.concurrent. + + //----------Классы синхронизации---------- + // для training + CyclicBarrier cb = new CyclicBarrier(CARS_COUNT); + // для гонка началась + final CountDownLatch cdl = new CountDownLatch(CARS_COUNT); + // для тоннелeй + Semaphore smp = new Semaphore(CARS_COUNT/2); + // для финиша + + + // для гонка закончилась + final CountDownLatch cdlFin = new CountDownLatch(CARS_COUNT); + + + System.out.println("ВАЖНОЕ ОБЪЯВЛЕНИЕ >>> Подготовка!!!"); + //Создается новая трасса (длинна, тунели, дорога) + Race race = new Race(new Road(60), new Tunnel(smp), new Road(40)); + //Укороченная гонка для тестов + //Race race = new Race(new Tunnel(smp)); + Car[] cars = new Car[CARS_COUNT]; + // участники ( гонка? рандомная скорость) + for (int i = 0; i < cars.length; i++) { + cars[i] = new Car(race, 20 + (int) (Math.random() * 10),lock, cdlFin); + + } + + + // потоки участников + // 1 этап: подготовка + for (int i = 0; i < cars.length; i++) { + final int w = i; + new Thread(() -> { + // ожидаем всех на подготовке + cars[w].training(cb); + cdl.countDown(); + }).start(); + } + // ожидаем всех у линии старта + cdl.await(); + System.out.println("ВАЖНОЕ ОБЪЯВЛЕНИЕ >>> Гонка началась!!!"); + + // 2 этап: основная часть - гонка + for (int i = 0; i < cars.length; i++) { + new Thread(cars[i]).start(); + } + cdlFin.await(); + System.out.println("ВАЖНОЕ ОБЪЯВЛЕНИЕ >>> Гонка закончилась!!!"); + + } // psvm end + } // main class ends + + + +class Car implements Runnable { + private static int CARS_COUNT; + private Race race; + private int speed; + private String name; + + // добавленные поля + CountDownLatch cdlFin; + Lock lock; + + // + + public String getName() { + return name; + } + public int getSpeed() { + return speed; + } + public Car(Race race, int speed, Lock lock, CountDownLatch cdlFin) { + this.race = race; + this.speed = speed; + CARS_COUNT++; + this.name = "Участник #" + CARS_COUNT; + + this.lock=lock; + this.cdlFin = cdlFin; + } + + @Override + public void run() { + for (int i = 0; i < race.getStages().size(); i++) { + race.getStages().get(i).go(this); + + } + if (lock.tryLock()) { + System.out.println("Участник #" + " " + name + " ------------------win------------------"); + } + // не убираем лок, тк только один поток должен победить + //lock.unlock(); + + cdlFin.countDown(); + } + + public void training(CyclicBarrier cyclicBarrier){ + try { + System.out.println(this.name + " готовится"); + Thread.sleep(500 + (int)(Math.random() * 800)); + System.out.println(this.name + " готов"); + cyclicBarrier.await(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} + + +abstract class Stage { + protected int length; + protected String description; + public String getDescription() { + return description; + } + public abstract void go(Car c); +} +class Road extends Stage { + public Road(int length) { + this.length = length; + this.description = "Дорога " + length + " метров"; + } + @Override + public void go(Car c) { + try { + System.out.println(c.getName() + " начал этап: " + description); + Thread.sleep(length / c.getSpeed() * 1000); + System.out.println(c.getName() + " закончил этап: " + description); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} +class Tunnel extends Stage { + Semaphore smp; + public Tunnel(Semaphore smp) { + this.length = 80; + this.description = "Тоннель " + length + " метров"; + // Semaphore + this.smp = smp; + } + + @Override + public void go(Car c) { + try { + try { + if (!smp.tryAcquire()){ + System.out.println(c.getName() + " готовится к этапу(ждет): " + description); + // Semaphore + smp.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); + } + } catch (Exception e) { + e.printStackTrace(); + } + // Semaphore + smp.release(); + } +} + class Race { + private ArrayList stages; + public ArrayList getStages() { return stages; } + public Race(Stage... stages) { + this.stages = new ArrayList<>(Arrays.asList(stages)); + } + }