diff --git a/lib/junit-platform-console-standalone-1.13.0-M3.jar b/lib/junit-platform-console-standalone-1.13.0-M3.jar new file mode 100644 index 0000000..9a691d8 Binary files /dev/null and b/lib/junit-platform-console-standalone-1.13.0-M3.jar differ diff --git a/src/impl/Afficheur.java b/src/impl/Afficheur.java index b0929de..f28ce5a 100644 --- a/src/impl/Afficheur.java +++ b/src/impl/Afficheur.java @@ -9,7 +9,7 @@ import java.util.concurrent.Future; public class Afficheur implements ObserverdeCapteur { private int id= new Random().nextInt(100); - public ArrayList vals = new ArrayList(); + public ArrayList vals = new ArrayList(); //pour que les tests puissent lire les valeur après l'exécution public Afficheur() {} @@ -23,7 +23,7 @@ public class Afficheur implements ObserverdeCapteur { try{ Future futureValue= capteurAsync.getValue(); Integer value=futureValue.get(); - System.out.println("Afficheur " + id+", value: "+ value); + System.out.println("\t\tAfficheur " + id+", value: "+ value); vals.add(value); }catch(Exception e){ //TODO diff --git a/src/impl/CapteurImpl.java b/src/impl/CapteurImpl.java index 0a851f8..782d693 100644 --- a/src/impl/CapteurImpl.java +++ b/src/impl/CapteurImpl.java @@ -6,12 +6,18 @@ import interfaces.ObserverDeCapteurAsync; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; + public class CapteurImpl implements Capteur { + private ScheduledExecutorService scheduler; private int value = 0; private AlgoDiffusion diffusion; protected List observers=new ArrayList(); private Boolean locker = false; + private Boolean locker2 = false; + + private long initialTime = System.currentTimeMillis(); // debug @Override public void attach(ObserverDeCapteurAsync o) { @@ -25,20 +31,32 @@ public class CapteurImpl implements Capteur { @Override public void tick() { - System.out.println("\t\ttick"); - this.value++; + System.out.println("tick call"); if(!locker){ - diffusion.execute(); + this.value++; + System.out.println("tick(" + this.value+")\t\t" + (System.currentTimeMillis()-initialTime) + "ms"); + //diffusion.execute(); + if(!locker2){ + scheduler.execute(() -> diffusion.execute()); + } } } - public void lock(){ + public synchronized void lock(){ locker = true; } - public void unlock(){ + public synchronized void unlock(){ locker = false; } + public synchronized void lock2(){ + locker2 = true; + } + public synchronized void unlock2(){ + locker2 = false; + } + + public void setAlgoDiffusion(AlgoDiffusion diffusion){ this.diffusion = diffusion; } @@ -48,4 +66,11 @@ public class CapteurImpl implements Capteur { public int getValue() { return this.value; } + + public void setScheduler(ScheduledExecutorService scheduler){ + this.scheduler = scheduler; + } + + + } diff --git a/src/impl/DiffusionAtomique.java b/src/impl/DiffusionAtomique.java index db09267..42acf07 100644 --- a/src/impl/DiffusionAtomique.java +++ b/src/impl/DiffusionAtomique.java @@ -1,12 +1,9 @@ package impl; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import interfaces.AlgoDiffusion; -import interfaces.Capteur; import interfaces.ObserverDeCapteurAsync; public class DiffusionAtomique implements AlgoDiffusion { @@ -21,7 +18,8 @@ public class DiffusionAtomique implements AlgoDiffusion { @Override public void execute() { - capteur.lock(); + this.capteur.lock(); + System.out.println("execute"); Future[] l = new Future[capteur.observers.size()]; int i = 0; for (ObserverDeCapteurAsync canal : capteur.observers) { @@ -36,6 +34,6 @@ public class DiffusionAtomique implements AlgoDiffusion { e.printStackTrace(); } } - capteur.unlock(); + this.capteur.unlock(); } } diff --git a/src/impl/DiffusionEpoque.java b/src/impl/DiffusionEpoque.java new file mode 100644 index 0000000..64529b6 --- /dev/null +++ b/src/impl/DiffusionEpoque.java @@ -0,0 +1,41 @@ +package impl; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import interfaces.AlgoDiffusion; +import interfaces.ObserverDeCapteurAsync; + +public class DiffusionEpoque implements AlgoDiffusion { + + public CapteurImpl capteur; + + @Override + public void configure() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'configure'"); + } + + @Override + public void execute() { + this.capteur.lock2(); + System.out.println("execute"); + Future[] l = new Future[capteur.observers.size()]; + int i = 0; + for (ObserverDeCapteurAsync canal : capteur.observers) { + Future f = canal.update(); + l[i] = f; + i++; + } + + for (Future f : l) { //attend que les autres soient résolus //TODO + try { + f.get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } + this.capteur.unlock2(); + //this.capteur.unlock(); + } +} diff --git a/src/impl/DiffusionSequencielle.java b/src/impl/DiffusionSequencielle.java new file mode 100644 index 0000000..c67daeb --- /dev/null +++ b/src/impl/DiffusionSequencielle.java @@ -0,0 +1,56 @@ +package impl; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import interfaces.AlgoDiffusion; +import interfaces.ObserverDeCapteurAsync; + +public class DiffusionSequencielle implements AlgoDiffusion { + + public CapteurImpl capteur; + + @Override + public void configure() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'configure'"); + } + + @Override + public void execute() { + this.capteur.lock2(); + System.out.println("execute"); + Future[] l = new Future[capteur.observers.size()]; + int i = 0; + for (ObserverDeCapteurAsync canal : capteur.observers) { + Future f = canal.update(); + l[i] = f; + i++; + } + boolean firstDone = false; + + while(!firstDone){ //attend que le premier futur soit résolu + for (Future f : l) { + if(f.isDone()){ + this.capteur.lock(); //lock le capteur pour que les autres puissent lire la même valeur que le premier + firstDone = true; + } + } + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + for (Future f : l) { //attend que les autres soient résolus + try { + f.get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + } + this.capteur.unlock2(); + this.capteur.unlock(); + } +} diff --git a/src/impl/Scheduler.java b/src/impl/Scheduler.java index b2ee01d..97f4ecd 100644 --- a/src/impl/Scheduler.java +++ b/src/impl/Scheduler.java @@ -7,7 +7,7 @@ public class Scheduler { public Scheduler(int nbCanaux) { int nThread = 20+2*nbCanaux; - scheduler = Executors.newScheduledThreadPool(nThread); + this.scheduler = Executors.newScheduledThreadPool(nThread); } public ScheduledExecutorService getScheculer(){ diff --git a/src/main.java b/src/main.java index fae6193..6b6104f 100644 --- a/src/main.java +++ b/src/main.java @@ -1,5 +1,3 @@ -import java.util.Timer; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -7,8 +5,9 @@ import impl.Afficheur; import impl.Canal; import impl.CapteurImpl; import impl.DiffusionAtomique; +import impl.DiffusionEpoque; +import impl.DiffusionSequencielle; import impl.Scheduler; -import interfaces.AlgoDiffusion; public class main { @@ -18,10 +17,16 @@ public class main { public static void main(String[] argv){ Scheduler scheduler = new Scheduler(NB_CANAUX); CapteurImpl c = new CapteurImpl(); + c.setScheduler(scheduler.getScheculer()); - DiffusionAtomique algo = new DiffusionAtomique(); - algo.capteur = c; - c.setAlgoDiffusion(algo); + DiffusionAtomique algoAtom = new DiffusionAtomique(); + algoAtom.capteur = c; + DiffusionSequencielle algoSeq = new DiffusionSequencielle(); + algoSeq.capteur = c; + DiffusionEpoque algoEpoq = new DiffusionEpoque(); + algoEpoq.capteur = c; + + c.setAlgoDiffusion(algoEpoq); for(int i = 0; i[] rAtom = testAtom(); - System.out.println("\noracle:\n"); - Boolean r = oracleAtom(rAtom); - System.out.println("Test : " + r); - - } catch (Exception e) { - // TODO: handle exception - } - - // oracle vérifit le résultat - - } - - private static List[] testAtom() throws InterruptedException{ - - ArrayList[] r = new ArrayList[NB_CANAUX]; - for(int i = 0; i(); - } - - Afficheur[] a = new Afficheur[NB_CANAUX]; - - Scheduler scheduler = new Scheduler(NB_CANAUX); - CapteurImpl c = new CapteurImpl(); - - DiffusionAtomique algo = new DiffusionAtomique(); - algo.capteur = c; - c.setAlgoDiffusion(algo); - - for(int i = 0; i c.tick(), 0, 500, TimeUnit.MILLISECONDS); - - Thread.sleep(5000); - - clock.close(); - - Thread.sleep(1500); - - for(int i = 0; i[] resultats){ - boolean r = true; - int testSize = -1; - for(int i = 0; i< NB_CANAUX && r; i++){ - - if(testSize!=-1) { - r = r && resultats[i].size() == testSize; - } - else { - testSize = resultats[i].size(); - } - int valTest = 1; - for(int j = 0; j< resultats[i].size() && r; j++){ - System.out.print(resultats[i].get(j) + " - "); - r = r && resultats[i].get(j)==valTest; - valTest++; - } - System.out.println(resultats[i].size()+"---- "); - } - return r; - } - -} diff --git a/src/test/TestAlgoDiffusionAtom.java b/src/test/TestAlgoDiffusionAtom.java new file mode 100644 index 0000000..9aaf395 --- /dev/null +++ b/src/test/TestAlgoDiffusionAtom.java @@ -0,0 +1,96 @@ +package test; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + + + +import impl.Afficheur; +import impl.Canal; +import impl.CapteurImpl; +import impl.DiffusionAtomique; +import impl.Scheduler; + +public class TestAlgoDiffusionAtom { + + static int NB_CANAUX = 3; + public static List[] rAtom; + + + @BeforeAll + public static void testAtom() throws InterruptedException{ + + ArrayList[] r = new ArrayList[NB_CANAUX]; + for(int i = 0; i(); + } + + Afficheur[] a = new Afficheur[NB_CANAUX]; + + Scheduler scheduler = new Scheduler(NB_CANAUX); + CapteurImpl c = new CapteurImpl(); + c.setScheduler(scheduler.getScheculer()); + + DiffusionAtomique algo = new DiffusionAtomique(); + algo.capteur = c; + c.setAlgoDiffusion(algo); + + for(int i = 0; i future = clock.scheduleAtFixedRate(() -> c.tick(), 0, 500, TimeUnit.MILLISECONDS); + + Thread.sleep(10000); + System.out.println("STOP"); + System.out.println("waitting for lasts display..."); + future.cancel(false); + Thread.sleep(3100); //3000ms max + 100ms de marge + + clock.shutdown(); + //Thread.sleep(1500); + + for(int i = 0; i[] rEpoq; + + + @BeforeAll + public static void testAtom() throws InterruptedException{ + + ArrayList[] r = new ArrayList[NB_CANAUX]; + for(int i = 0; i(); + } + + Afficheur[] a = new Afficheur[NB_CANAUX]; + + Scheduler scheduler = new Scheduler(NB_CANAUX); + CapteurImpl c = new CapteurImpl(); + c.setScheduler(scheduler.getScheculer()); + + DiffusionEpoque algo = new DiffusionEpoque(); + algo.capteur = c; + c.setAlgoDiffusion(algo); + + for(int i = 0; i future = clock.scheduleAtFixedRate(() -> c.tick(), 0, 500, TimeUnit.MILLISECONDS); + + Thread.sleep(10000); + System.out.println("STOP"); + System.out.println("waitting for lasts display..."); + future.cancel(false); + Thread.sleep(3100); //3000ms max + 100ms de marge + + clock.shutdown(); + //Thread.sleep(1500); + + for(int i = 0; ivalTest; + valTest=rEpoq[i].get(j); + } + System.out.println(" "); + } + assertTrue(r); + } + +} diff --git a/src/test/TestAlgoDiffusionSeq.java b/src/test/TestAlgoDiffusionSeq.java new file mode 100644 index 0000000..17e3f95 --- /dev/null +++ b/src/test/TestAlgoDiffusionSeq.java @@ -0,0 +1,107 @@ +package test; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + + + +import impl.Afficheur; +import impl.Canal; +import impl.CapteurImpl; +import impl.DiffusionAtomique; +import impl.DiffusionSequencielle; +import impl.Scheduler; + +public class TestAlgoDiffusionSeq { + + static int NB_CANAUX = 3; + public static List[] rSeq; + + + @BeforeAll + public static void testAtom() throws InterruptedException{ + + ArrayList[] r = new ArrayList[NB_CANAUX]; + for(int i = 0; i(); + } + + Afficheur[] a = new Afficheur[NB_CANAUX]; + + Scheduler scheduler = new Scheduler(NB_CANAUX); + CapteurImpl c = new CapteurImpl(); + c.setScheduler(scheduler.getScheculer()); + + DiffusionSequencielle algo = new DiffusionSequencielle(); + algo.capteur = c; + c.setAlgoDiffusion(algo); + + for(int i = 0; i future = clock.scheduleAtFixedRate(() -> c.tick(), 0, 500, TimeUnit.MILLISECONDS); + + Thread.sleep(10000); + System.out.println("STOP"); + System.out.println("waitting for lasts display..."); + future.cancel(false); + Thread.sleep(3100); //3000ms max + 100ms de marge + + clock.shutdown(); + //Thread.sleep(1500); + + for(int i = 0; itest; + test = rSeq[i].get(j); + } + else{ + r = r && rSeq[i].get(j) == test; + } + } + } + + //display + for(int i = 0; i< NB_CANAUX && r; i++){ + System.out.println("canal " + i + ":"); + for(int j = 0; j< rSeq[i].size() && r; j++){ + System.out.print(rSeq[i].get(j)); + if(j