1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
| import java.util.Hashtable;
import java.util.ArrayList;
import java.util.List;
import java.util.Date; // debug
public class Traiteur extends Thread {
private String threadMessage;
private Integer threadId;
//private static Hashtable<Integer, Enregistrement> synchronizer = new Hashtable<Integer, Enregistrement>();
private static Hashtable<Integer, Enregistrement> synchronizer = new Hashtable<Integer, Enregistrement>();
/* Constructeur avec parametres */
public Traiteur(Integer identifiant, String message) {
this.threadMessage = message;
this.threadId=identifiant;
}
/* La fonction regarde si les proprietes du thread sont deja dans le synchronizer */
public boolean utiliserSynchronizer() {
boolean estPresent = false;
// Creation de l'enregistrement a mettre la Synchronizer
Enregistrement monRec = new Enregistrement(threadMessage);
// Creation de l'enregistrement qu'on recuperera du Synchronizer
Enregistrement existant;
// Verrouillage du Synchronizer ( http://rom.developpez.com/java-synchronisation/#LII-A )
synchronized(synchronizer) {
//DEBUG
//System.out.println("\tJe suis : " + monRec.toString());
if(true==synchronizer.containsKey(threadId)) {
estPresent = true;
// Le traitement se fait plus tard
}
else {
// Ajout de notre enregistrement dans Synchronizer
synchronizer.put(threadId, monRec);
estPresent = false;
}
}
/* On libere au plus vite la Hashtable. Ainsi, d'autres threads peuvent y accéder.
* Dans la suite, on fait l'action necessaire en fonction de la variable "estPresent"
*/
if(false==estPresent) {
// On peut car on l'a deja insere l'enregistrement
//existant = synchronizer.get(threadId);
//Object eVerrou = existant.getVerrou();
//synchronized(eVerrou) {
synchronized (monRec.getVerrou() ) {
// On simule le traitement d'encode du record
try {
System.out.println("On commence a encoder (" + threadMessage + ")");
sleep(100);
System.out.println("On termine d'encoder (" + threadMessage + ")");
}
catch(Exception ex){}
}
}
else {
// Recuperation de cet enregistrement
existant = synchronizer.get(threadId);
Object eVerrou = existant.getVerrou();
Integer eCompteur = existant.getCompteur();
System.out.println( "\tJ'ai lu : " + existant.toString() + "(" + threadMessage + ")");
// Comparer la date
//if( monRec.getDate().after(existant.getDate())==false )
if(false) {
//System.out.println("On rejette l'enregistrement (" + threadMessage + ")");
}
else {
// On se met en attente de l'enregistrement
synchronized(eCompteur) {
existant.setCompteur(existant.getCompteur() + 1);
System.out.println("On attend notre tour... (" + threadMessage + ")");
}
// On attend notre tour...
synchronized(eVerrou) {
System.out.println("On a obtenu le verrou (" + threadMessage + ")");
// On n'est plus en attente donc on decremente le verrou
existant.setCompteur(existant.getCompteur() - 1);
// On remplace avec nos donnees
existant.setDebugTxt( existant.getDebugTxt() + "_" + monRec.getDebugTxt() );
// On simule le traitement d'encode du record
try {
System.out.println("On commence a encoder.... (" + threadMessage + ")");
sleep(100);
System.out.println("On termine d'encoder (" + threadMessage + ")");
}
catch(Exception ex){}
} // section critique sur l'enregistrement
}
}//esPresent ?
return estPresent;
}
/* Fonction qui sera execute par chaque thread */
@Override
public void run() {
//System.out.println("Run du thread " + threadId + "/" + threadMessage);
try {
sleep(20); // simule les traitements avant l'encodage du record
utiliserSynchronizer(); // on y encode le record
}
catch(Exception ex) {
System.out.println("Le thread " + threadId + " a rencontre une exception !");
ex.printStackTrace();
}
//System.out.println("Fin du thread " + threadId + "/" + threadMessage);
}
/* Programme de test */
public static void main (String [] args)
{
System.out.println("Debut du programme PocVerrou...");
System.out.println(new Date() + "\n\n");
// Conteneur des threads
List<Traiteur> mesTraiteurs = new ArrayList<Traiteur>();
// Lancement de threads
Traiteur t1 = new Traiteur(1, "Premier thread");
t1.start();
mesTraiteurs.add(t1);
try { sleep(5); } catch(Exception ex){}
Traiteur t2 = new Traiteur(1, "Second thread");
t2.start();
mesTraiteurs.add(t2);
try { sleep(5); } catch(Exception ex){}
Traiteur t3 = new Traiteur(1, "Troisieme thread");
t3.start();
mesTraiteurs.add(t3);
try { sleep(5); } catch(Exception ex){}
Traiteur t4 = new Traiteur(1, "Quatrieme thread");
t4.start();
mesTraiteurs.add(t4);
try { sleep(5); } catch(Exception ex){}
Traiteur t5 = new Traiteur(1, "Cinquieme thread");
t5.start();
mesTraiteurs.add(t5);
/*
for (int i=1; i<=15; i++) {
Traiteur monTraiteur = new Traiteur(i, String.valueOf(i)+"_A");
monTraiteur.start();
mesTraiteurs.add(monTraiteur);
}
*/
// Attente de tous les threads
for (Traiteur monTraiteur : mesTraiteurs) {
try {
monTraiteur.join();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
// Terminer le main
System.out.println("\nContenu de Synchronizer :");
System.out.print(synchronizer.toString());
System.out.println("\n\nFin du programme PocVerrou");
System.out.println(new Date() );
}
}// class Traiteur |
Partager