test (à clean), essai de diffusion asynchrone qui utilise le scheluder dans CapteurImpl

This commit is contained in:
Rochas
2025-11-22 19:01:11 +01:00
parent ef954a0c48
commit 1659650450
12 changed files with 439 additions and 123 deletions

Binary file not shown.

View File

@@ -9,7 +9,7 @@ import java.util.concurrent.Future;
public class Afficheur implements ObserverdeCapteur {
private int id= new Random().nextInt(100);
public ArrayList<Integer> vals = new ArrayList();
public ArrayList<Integer> vals = new ArrayList<Integer>(); //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<Integer> 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

View File

@@ -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<ObserverDeCapteurAsync> observers=new ArrayList<ObserverDeCapteurAsync>();
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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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(){

View File

@@ -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<NB_CANAUX; i++){
Afficheur afficheur = new Afficheur();

View File

@@ -1,104 +0,0 @@
package test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import impl.Afficheur;
import impl.Canal;
import impl.CapteurImpl;
import impl.DiffusionAtomique;
import impl.Scheduler;
public class Test {
static int NB_CANAUX = 3;
public static void main(String[] argv){
//DiffusionSequencielle algoSeq = new DiffusionSequencielle;
//DiffusionEpoque algoEpoque = new DiffusionEpoque();
//test : génère un résultat
try {
List<Integer>[] 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<Integer>[] testAtom() throws InterruptedException{
ArrayList<Integer>[] r = new ArrayList[NB_CANAUX];
for(int i = 0; i<NB_CANAUX; i++){
r[i] = new ArrayList<Integer>();
}
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<NB_CANAUX; i++){
Afficheur afficheur = new Afficheur();
afficheur.setId(i);
a[i] = afficheur;
Canal canal = new Canal(c, scheduler, afficheur);
c.attach(canal);
}
ScheduledExecutorService clock = scheduler.getScheculer();
clock.scheduleAtFixedRate(() -> c.tick(), 0, 500, TimeUnit.MILLISECONDS);
Thread.sleep(5000);
clock.close();
Thread.sleep(1500);
for(int i = 0; i<NB_CANAUX; i++){
r[i] = a[i].vals;
System.out.println("\n"+a[i].vals.size());
for(int j = 0; j<r[i].size(); j ++){
System.out.print(r[i].get(j) + "-");
}
}
return r;
}
private static boolean oracleAtom(List<Integer>[] 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;
}
}

View File

@@ -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<Integer>[] rAtom;
@BeforeAll
public static void testAtom() throws InterruptedException{
ArrayList<Integer>[] r = new ArrayList[NB_CANAUX];
for(int i = 0; i<NB_CANAUX; i++){
r[i] = new ArrayList<Integer>();
}
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<NB_CANAUX; i++){
Afficheur afficheur = new Afficheur();
afficheur.setId(i);
a[i] = afficheur;
Canal canal = new Canal(c, scheduler, afficheur);
c.attach(canal);
}
ScheduledExecutorService clock = scheduler.getScheculer();
ScheduledFuture<?> 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<NB_CANAUX; i++){
r[i] = a[i].vals;
}
rAtom = r;
}
@Test
void testAtomOracle(){
boolean r = true;
for(int i = 0; i< NB_CANAUX-1 && r; i++){
r = rAtom[i].size()==rAtom[i+1].size();
}
if(!r) System.out.println("pas de la même taille :");
for(int i = 0; i< NB_CANAUX && r; i++){
int valTest = 1;
System.out.println("canal " + i + ":");
for(int j = 0; j< rAtom[i].size() && r; j++){
System.out.print(rAtom[i].get(j));
if(j<rAtom[i].size()-1) System.out.print(", ");
r = r && rAtom[i].get(j)==valTest;
valTest++;
}
System.out.println(" ");
}
assertTrue(r);
}
}

View File

@@ -0,0 +1,92 @@
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.DiffusionEpoque;
import impl.Scheduler;
public class TestAlgoDiffusionEpoq {
static int NB_CANAUX = 3;
public static List<Integer>[] rEpoq;
@BeforeAll
public static void testAtom() throws InterruptedException{
ArrayList<Integer>[] r = new ArrayList[NB_CANAUX];
for(int i = 0; i<NB_CANAUX; i++){
r[i] = new ArrayList<Integer>();
}
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<NB_CANAUX; i++){
Afficheur afficheur = new Afficheur();
afficheur.setId(i);
a[i] = afficheur;
Canal canal = new Canal(c, scheduler, afficheur);
c.attach(canal);
}
ScheduledExecutorService clock = scheduler.getScheculer();
ScheduledFuture<?> 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<NB_CANAUX; i++){
r[i] = a[i].vals;
}
rEpoq = r;
}
@Test
void testAtomOracle(){
boolean r = true;
for(int i = 0; i< NB_CANAUX && r; i++){
int valTest = 0;
System.out.println("canal " + i + ":");
for(int j = 0; j< rEpoq[i].size() && r; j++){
System.out.print(rEpoq[i].get(j));
if(j<rEpoq[i].size()-1) System.out.print(", ");
r = r && rEpoq[i].get(j)>valTest;
valTest=rEpoq[i].get(j);
}
System.out.println(" ");
}
assertTrue(r);
}
}

View File

@@ -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<Integer>[] rSeq;
@BeforeAll
public static void testAtom() throws InterruptedException{
ArrayList<Integer>[] r = new ArrayList[NB_CANAUX];
for(int i = 0; i<NB_CANAUX; i++){
r[i] = new ArrayList<Integer>();
}
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<NB_CANAUX; i++){
Afficheur afficheur = new Afficheur();
afficheur.setId(i);
a[i] = afficheur;
Canal canal = new Canal(c, scheduler, afficheur);
c.attach(canal);
}
ScheduledExecutorService clock = scheduler.getScheculer();
ScheduledFuture<?> 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<NB_CANAUX; i++){
r[i] = a[i].vals;
}
rSeq = r;
}
@Test
void testAtomOracle(){
boolean r = true;
for(int i = 0; i< NB_CANAUX-1 && r; i++){
r = rSeq[i].size()==rSeq[i+1].size();
}
if(!r) System.out.println("pas de la même taille :");
int test = 0;
for(int j = 0; j< rSeq[0].size() && r; j++){
for(int i = 0; i< NB_CANAUX && r; i++){
if(i==0){
r = r && rSeq[i].get(j)>test;
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<rSeq[i].size()-1) System.out.print(", ");
}
System.out.println(" ");
}
assertTrue(r);
}
}