Ici, je laisse un exemple pour le modèle à l’aide d’un sémaphoro:
import java.security.SecureRandom;import java.util.concurrent.Semaphore;import java.util.concurrent.atomic.AtomicInteger;/** * @author snolde * */public class Tuberia { class Hilo extends Thread{ int id; public Hilo(int id){ this.id=id; } @Override public void run() { hil(id); } } static SecureRandom sr = new SecureRandom(); Semaphore guardia; AtomicInteger count = new AtomicInteger(0); public Tuberia(int limite){ guardia = new Semaphore(limite, true); } public void hil(int id){ try { guardia.acquire(); } catch (InterruptedException e) {} synchronized(count){ System.out.println(String.format("Hilo %d entró (%d)", id, count.incrementAndGet())); } try { // simulación de código productivo, carga de 500-1000 ms Thread.sleep(500+sr.nextInt(500)); } catch (InterruptedException e) {} synchronized(count){ System.out.println(String.format("Hilo %d salió (%d)", id, count.decrementAndGet())); } guardia.release(); } public void creaHilos(int num){ for (int i = 1; i<=num; i++){ new Hilo(i).start(); try { // variable Thread.sleep(10); } catch (InterruptedException e) {} } } public static void main(String args) { Tuberia tub = new Tuberia(5); tub.creaHilos(10); }}
avec la classe Hilo
déclarée de classe interne n’est pas nécessaire pour expliquer la référence à Tuberia
car il a accès à Les procédés de la classe mère.
Le compteur est inclus dans des blocs courts synchronisés pour vous assurer que les événements sont imprimés dans la séquence qui se produisent.
Le feu de la circulation dans l’exemple limite la Nombre de threads qui ont accès au code entre acquire
et release
La principale différence entre les deux implémentations est-ce qu’avec le feu de circulation, un certain nombre de threads peuvent accéder au code simultanément tandis que la méthode synchronisée garantit qu’un seul thread peut accéder à ce bloc de code, ce qui en fait une action atomique.
si cela aucun sens n’est visible dans un exemple aussi fondamental, sans penser que c’est vraiment le travail qu’ils effectuent les threads et quelles ressources dont ils ont besoin pour cela.
Pour expérimenter le comportement, modifier des pauses en génération de nouveaux Des brins, le nombre de brins, la quantité d’autorisations ou du temps aléatoire pour la charge du code.