java.util.concurrent
Par liguorien, mercredi 18 février 2009 à 11:12 :: Java :: #212 :: rss
Ce package introduit dans le jdk 1.5 est assez utile pour les développeurs qui doivent affronter la synchronisation dans une application ayant recourt à beaucoup de Thread. Chose qui devient complexe assez rapidement. Voici un bout de code qui utilise deux classes fournit par ce package. ReentrantLock et CyclicBarrier.
Le ReentrantLock est en quelque sorte le descendant du mot clef synchronized. Il n'y a qu'un seul Thread à la fois qui peut obtenir le lock, tout les autres Thread qui essayent d'obtenir le lock se mettront en file d'attente jusqu'à temps le possesseur du lock se libère.
Le CyclicBarrier est utile pour synchroniser plusieurs Thread afin qu'ils s'attendent à des points préçis dans le code.
Voici donc un bout de code qui utilise ces deux classes. Le manager à quatre "worker thread" qui font une tâche quelquonque, lorsqu'ils ont finit leur tâche, ils doivent notifier le manager. On veut synchroniser cette notification, donc nous allons utiliser un ReentrantLock. Lorsque la notification est terminé, on veut que les Workers attendent que tout les autres notifications soient terminés avant de continuer leut tâche. Donc nous allons utiliser un CyclicBarrier.
Le CyclicBarrier est utile pour synchroniser plusieurs Thread afin qu'ils s'attendent à des points préçis dans le code.
Voici donc un bout de code qui utilise ces deux classes. Le manager à quatre "worker thread" qui font une tâche quelquonque, lorsqu'ils ont finit leur tâche, ils doivent notifier le manager. On veut synchroniser cette notification, donc nous allons utiliser un ReentrantLock. Lorsque la notification est terminé, on veut que les Workers attendent que tout les autres notifications soient terminés avant de continuer leut tâche. Donc nous allons utiliser un CyclicBarrier.
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;
public class MyManager {
public final static int NUM_WORKERS = 4;
private ReentrantLock _lock;
private CyclicBarrier _barrier;
private ExecutorService _executor;
public MyManager() {
_lock = new ReentrantLock();
_barrier = new CyclicBarrier(NUM_WORKERS);
_executor = Executors.newCachedThreadPool();
for (int i = 0; i < NUM_WORKERS; i++) {
_executor.execute(new Worker());
}
}
private void doSomething() throws Exception {
String myName = Thread.currentThread().getName();
System.out.println(myName + " trying to acquire lock");
_lock.lock();
System.out.println(myName + " has acquired lock");
Thread.sleep(2000);
System.out.println(myName + " is trying to release lock");
_lock.unlock();
System.out.println(myName + " has released lock and waiting for others");
_barrier.await();
System.out.println(myName + " has finished waiting");
}
class Worker implements Runnable {
public void run() {
try {
while (true) {
// do something...
Thread.sleep(1000);
// do something else
doSomething();
}
} catch (Throwable ex) {
ex.printStackTrace();
} finally {
// clean up stuff
}
}
}
public Thread getShutdownHook() {
return new Thread() {
@Override
public void run() {
shutdown();
}
};
}
private void shutdown() {
_executor.shutdownNow();
}
}
public class Main {
public static void main(String[] args) {
MyManager mgr = new MyManager();
Runtime.getRuntime().addShutdownHook(mgr.getShutdownHook());
}
}
Et voilà, mon quota de post concernant le code est rempli pour l'année! ^^
Commentaires
Aucun commentaire pour le moment.
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.