From b46057c14d2401b3353df1e8e243c4f9ac9bb6d8 Mon Sep 17 00:00:00 2001 From: unknown <david.antunes-da-silva@etu.univ-tlse2.fr> Date: Thu, 23 Jun 2022 11:42:18 +0200 Subject: [PATCH] Add ThreeStepCycling scheduler + fix minor bugs/mistakes --- src/example/philosophes/MainPhilosophe.java | 7 +- src/example/philosophes/Philosopher.java | 39 +++---- src/example/randomants/MainAnt.java | 2 +- .../{base => }/schedulers/AsyncCycling.java | 20 ++-- .../{base => }/schedulers/FairCycling.java | 42 +++---- .../{base => }/schedulers/FairPosCycling.java | 2 +- .../PausableThreadPoolExecutor.java | 2 +- .../variations/ThreeStepCycling.java | 105 ++++++++++++++++++ .../variations}/TwoDCycling.java | 5 +- src/mas/ui/SchedulerToolbar.java | 4 +- 10 files changed, 167 insertions(+), 61 deletions(-) rename src/mas/implementation/{base => }/schedulers/AsyncCycling.java (89%) rename src/mas/implementation/{base => }/schedulers/FairCycling.java (80%) rename src/mas/implementation/{base => }/schedulers/FairPosCycling.java (93%) rename src/mas/implementation/{base => }/schedulers/PausableThreadPoolExecutor.java (97%) create mode 100644 src/mas/implementation/schedulers/variations/ThreeStepCycling.java rename src/mas/implementation/{base/schedulers => schedulers/variations}/TwoDCycling.java (94%) diff --git a/src/example/philosophes/MainPhilosophe.java b/src/example/philosophes/MainPhilosophe.java index d70319a..64e0367 100644 --- a/src/example/philosophes/MainPhilosophe.java +++ b/src/example/philosophes/MainPhilosophe.java @@ -1,7 +1,8 @@ package example.philosophes; import mas.core.Schedulable; -import mas.implementation.base.schedulers.FairCycling; +import mas.implementation.schedulers.FairCycling; +import mas.implementation.schedulers.variations.ThreeStepCycling; public class MainPhilosophe { @@ -27,8 +28,8 @@ public class MainPhilosophe { philosophers[i].setRightPhilosopher(philosophers[(i+1) % nAgents]); } - Schedulable scheduler = new FairCycling(philosophers); - scheduler.setSleep(2); + Schedulable scheduler = new ThreeStepCycling(philosophers); + scheduler.setSleep(100); scheduler.start(); try { diff --git a/src/example/philosophes/Philosopher.java b/src/example/philosophes/Philosopher.java index d683258..18831e4 100644 --- a/src/example/philosophes/Philosopher.java +++ b/src/example/philosophes/Philosopher.java @@ -65,19 +65,13 @@ public class Philosopher extends Agent { @Override public void perceive() { - //System.out.println("Philosopher num " + id + " perceive"); + System.out.println("Philosopher num " + id + " perceive"); criticallity = computeCriticallity(); } @Override public void decide() { - //System.out.println("Philosopher num " + id + " decide"); - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + System.out.println("Philosopher num " + id + " decide"); State nextState = state; switch (state) { @@ -116,12 +110,24 @@ public class Philosopher extends Agent { state = nextState; //System.out.println("Philospher n°" + id + " / State " + state); - System.out.println( + /*System.out.println( "\tPhilosopher num " + id + " : " + state + " / " + criticallity + " / " + eatenPastas - /* + "\n\t\t Right Fk : " + rightFork.getTakenBy().getId() + " / Left Fk : " + leftFork.getTakenBy().getId()*/ - ); + + "\n\t\t Right Fk : " + rightFork.getTakenBy().getId() + " / Left Fk : " + leftFork.getTakenBy().getId() + );*/ + } + + @Override + public void act() { + System.out.println("Philosopher num " + id + " act"); + scheduler.addCyclable(new Waste(id)); + } + + @Override + public boolean terminate() { + return false; } + private Philosopher getMostCriticalNeighbor() { List<Philosopher> criticalest = new ArrayList<>(); double maxCriticality = getHungerDuration(); @@ -148,17 +154,6 @@ public class Philosopher extends Agent { return -1; } - @Override - public void act() { - //System.out.println("Philosopher num " + id + " act"); - scheduler.addCyclable(new Waste(id)); - } - - @Override - public boolean terminate() { - return false; - } - public Set<Map.Entry<Philosopher,Double>> getNeighborsCriticallity(){ Map<Philosopher, Double> criticalities = new HashMap<>(); diff --git a/src/example/randomants/MainAnt.java b/src/example/randomants/MainAnt.java index f7fc3fa..3944436 100644 --- a/src/example/randomants/MainAnt.java +++ b/src/example/randomants/MainAnt.java @@ -3,7 +3,7 @@ package example.randomants; import mas.core.Agent; import mas.core.Cyclable; import mas.environment.TwoDContinuosGrid; -import mas.implementation.base.schedulers.TwoDCycling; +import mas.implementation.schedulers.variations.TwoDCycling; import mas.ui.MainWindow; import mas.ui.SchedulerToolbar; diff --git a/src/mas/implementation/base/schedulers/AsyncCycling.java b/src/mas/implementation/schedulers/AsyncCycling.java similarity index 89% rename from src/mas/implementation/base/schedulers/AsyncCycling.java rename to src/mas/implementation/schedulers/AsyncCycling.java index 343f2fe..2b5073c 100644 --- a/src/mas/implementation/base/schedulers/AsyncCycling.java +++ b/src/mas/implementation/schedulers/AsyncCycling.java @@ -1,4 +1,4 @@ -package mas.implementation.base.schedulers; +package mas.implementation.schedulers; import mas.core.Cyclable; import mas.core.Schedulable; @@ -17,7 +17,7 @@ public class AsyncCycling implements Schedulable { private int sleep = DEFAULT_SLEEP; boolean mustStop = false; - private PausableThreadPoolExecutor executor = new PausableThreadPoolExecutor(); + protected PausableThreadPoolExecutor executor = new PausableThreadPoolExecutor(); public AsyncCycling(Cyclable... _cyclables){ @@ -84,14 +84,10 @@ public class AsyncCycling implements Schedulable { this.sleep = sleep; } - private void manageCyclable(Cyclable cyclable){ + protected void manageCyclable(Cyclable cyclable){ cyclable.cycle(); - try { - Thread.sleep(sleep); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + doSleep(); if(!cyclable.terminate() && !mustStop){ executor.execute(() -> manageCyclable(cyclable)); @@ -100,6 +96,12 @@ public class AsyncCycling implements Schedulable { } } - + protected void doSleep(){ + try { + Thread.sleep(sleep); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } } diff --git a/src/mas/implementation/base/schedulers/FairCycling.java b/src/mas/implementation/schedulers/FairCycling.java similarity index 80% rename from src/mas/implementation/base/schedulers/FairCycling.java rename to src/mas/implementation/schedulers/FairCycling.java index 468d989..2383a56 100644 --- a/src/mas/implementation/base/schedulers/FairCycling.java +++ b/src/mas/implementation/schedulers/FairCycling.java @@ -1,4 +1,4 @@ -package mas.implementation.base.schedulers; +package mas.implementation.schedulers; import mas.core.Cyclable; import mas.core.Schedulable; @@ -11,21 +11,21 @@ import java.util.concurrent.*; */ public class FairCycling implements Schedulable { - private Set<Cyclable> cyclables = new LinkedHashSet<>(); - private Queue<Cyclable> pendingToAddCyclables = new ConcurrentLinkedQueue<>(); + protected Set<Cyclable> cyclables = new LinkedHashSet<>(); + protected Queue<Cyclable> pendingToAddCyclables = new ConcurrentLinkedQueue<>(); - private int sleep = DEFAULT_SLEEP; + protected int sleep = DEFAULT_SLEEP; - private int nbOfCycles = 0; + protected int nbOfCycles = 0; protected boolean mustStop = false; protected boolean mustPause = false; - ExecutorService executor = Executors.newCachedThreadPool(); + protected ExecutorService executor = Executors.newCachedThreadPool(); - CountDownLatch pauseLatch; - CountDownLatch latch; + protected CountDownLatch pauseLatch; + protected CountDownLatch cycleLatch; public FairCycling(Cyclable... _cyclables) { @@ -88,7 +88,7 @@ public class FairCycling implements Schedulable { treatPendingCyclables(); - latch = new CountDownLatch(cyclables.size()); + cycleLatch = new CountDownLatch(cyclables.size()); for (Cyclable cyclable : cyclables) { @@ -97,20 +97,14 @@ public class FairCycling implements Schedulable { if(!cyclable.terminate()){ pendingToAddCyclables.add(cyclable); } - latch.countDown(); + cycleLatch.countDown(); }); } - if (getSleep() != 0) { - try { - Thread.sleep(getSleep()); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } + doSleep(); try { - latch.await(); + cycleLatch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -138,12 +132,22 @@ public class FairCycling implements Schedulable { } } - private void treatPendingCyclables() { + protected void treatPendingCyclables() { Queue<Cyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddCyclables); cyclables.addAll(buffer); pendingToAddCyclables.clear(); } + protected void doSleep(){ + if (getSleep() != 0) { + try { + Thread.sleep(getSleep()); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + } + } + public int getNbOfCycles() { return nbOfCycles; } diff --git a/src/mas/implementation/base/schedulers/FairPosCycling.java b/src/mas/implementation/schedulers/FairPosCycling.java similarity index 93% rename from src/mas/implementation/base/schedulers/FairPosCycling.java rename to src/mas/implementation/schedulers/FairPosCycling.java index 3100732..59bec2b 100644 --- a/src/mas/implementation/base/schedulers/FairPosCycling.java +++ b/src/mas/implementation/schedulers/FairPosCycling.java @@ -1,4 +1,4 @@ -package mas.implementation.base.schedulers; +package mas.implementation.schedulers; import mas.core.Cyclable; import mas.core.Schedulable; diff --git a/src/mas/implementation/base/schedulers/PausableThreadPoolExecutor.java b/src/mas/implementation/schedulers/PausableThreadPoolExecutor.java similarity index 97% rename from src/mas/implementation/base/schedulers/PausableThreadPoolExecutor.java rename to src/mas/implementation/schedulers/PausableThreadPoolExecutor.java index 8529943..cc2dc64 100644 --- a/src/mas/implementation/base/schedulers/PausableThreadPoolExecutor.java +++ b/src/mas/implementation/schedulers/PausableThreadPoolExecutor.java @@ -1,4 +1,4 @@ -package mas.implementation.base.schedulers; +package mas.implementation.schedulers; import java.util.concurrent.*; import java.util.concurrent.locks.Condition; diff --git a/src/mas/implementation/schedulers/variations/ThreeStepCycling.java b/src/mas/implementation/schedulers/variations/ThreeStepCycling.java new file mode 100644 index 0000000..4730051 --- /dev/null +++ b/src/mas/implementation/schedulers/variations/ThreeStepCycling.java @@ -0,0 +1,105 @@ +package mas.implementation.schedulers.variations; + +import mas.core.ThreeStepCyclable; +import mas.implementation.schedulers.FairCycling; + +import java.util.LinkedHashSet; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CountDownLatch; + +/** + * Execution cadencé en 3 phases (tous perception puis tous decision puis tous action) + */ + + +public class ThreeStepCycling extends FairCycling { + + protected Set<ThreeStepCyclable> threeStepCyclables = new LinkedHashSet<>(); + protected Queue<ThreeStepCyclable> pendingToAddThreeStepCyclabes = new ConcurrentLinkedQueue<>(); + + protected CountDownLatch perceptionLatch; + protected CountDownLatch decicionLatch; + + public ThreeStepCycling(ThreeStepCyclable... _threeStepCyclables){ + for(ThreeStepCyclable threeStepCyclable : _threeStepCyclables){ + addThreeStepCyclable(threeStepCyclable); + } + } + + @Override + protected void step() { + nbOfCycles++; + + treatPendingCyclables(); + + cycleLatch = new CountDownLatch(threeStepCyclables.size()); + perceptionLatch = new CountDownLatch(threeStepCyclables.size()); + decicionLatch = new CountDownLatch(threeStepCyclables.size()); + + for(ThreeStepCyclable threeStepCyclable : threeStepCyclables){ + + executor.execute(() -> { + threeStepCyclable.perceive(); + + waitPerception(); + + threeStepCyclable.decide(); + + waitDecision(); + + threeStepCyclable.act(); + + if(!threeStepCyclable.terminate()){ + pendingToAddThreeStepCyclabes.add(threeStepCyclable); + } + cycleLatch.countDown(); + }); + } + + doSleep(); + + try { + cycleLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + cyclables.clear(); + + onCycleEnds(); + } + + @Override + protected void treatPendingCyclables() { + Queue<ThreeStepCyclable> buffer = new ConcurrentLinkedQueue<>(pendingToAddThreeStepCyclabes); + threeStepCyclables.addAll(buffer); + pendingToAddThreeStepCyclabes.clear(); + } + + public void addThreeStepCyclable(ThreeStepCyclable threeStepCyclable){ + threeStepCyclable.setScheduler(this); + pendingToAddThreeStepCyclabes.add(threeStepCyclable); + } + + protected void waitPerception(){ + perceptionLatch.countDown(); + + try { + perceptionLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + protected void waitDecision(){ + decicionLatch.countDown(); + + try { + decicionLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/mas/implementation/base/schedulers/TwoDCycling.java b/src/mas/implementation/schedulers/variations/TwoDCycling.java similarity index 94% rename from src/mas/implementation/base/schedulers/TwoDCycling.java rename to src/mas/implementation/schedulers/variations/TwoDCycling.java index f1d942c..78cf03a 100644 --- a/src/mas/implementation/base/schedulers/TwoDCycling.java +++ b/src/mas/implementation/schedulers/variations/TwoDCycling.java @@ -1,13 +1,14 @@ -package mas.implementation.base.schedulers; +package mas.implementation.schedulers.variations; import mas.core.Cyclable; +import mas.implementation.schedulers.FairCycling; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; -public class TwoDCycling extends FairCycling{ +public class TwoDCycling extends FairCycling { /** * The state of the scheduler {@link State} diff --git a/src/mas/ui/SchedulerToolbar.java b/src/mas/ui/SchedulerToolbar.java index 5cd2b47..eab6a1d 100644 --- a/src/mas/ui/SchedulerToolbar.java +++ b/src/mas/ui/SchedulerToolbar.java @@ -1,6 +1,6 @@ package mas.ui; -import mas.implementation.base.schedulers.TwoDCycling; +import mas.implementation.schedulers.variations.TwoDCycling; import javax.swing.*; import java.awt.*; @@ -99,9 +99,7 @@ public class SchedulerToolbar extends JToolBar { if(!source.getValueIsAdjusting()){ switch (runController.getValue()) { case 0 -> { - System.out.println("Je commence doOneCycle()"); scheduler.doOneCycle(); - System.out.println("Je termine doOneCycle()"); } case 2 -> { scheduler.startWithSleep(1000); -- GitLab