Aici las un exemplu pentru model folosind un semaforo:
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); }}
cu clasa Hilo
declarată ca clasă internă nu este necesară pentru a explica referința la Tuberia
deoarece are acces la Metodele de la clasa părinte.
Contorul este inclus în blocuri scurte sincronizate pentru a se asigura că evenimentele sunt imprimate în secvența care apare.
Semafor în exemplul limitează Numărul de fire care au acces la codul dintre acquire
și iv id = „C449D010DE”
.
Diferența principală dintre cele două implementări Este faptul că, cu semaforul, există o serie de fire care pot accesa concomitent codul, în timp ce metoda sincronizată asigură că doar un fir poate accesa acest bloc de cod, făcând o acțiune atomică.
dacă asta nici un sens nu este vizibil într-un exemplu atât de important, fără a gândi că este într-adevăr lucrarea pe care o fac firele și ce resurse au nevoie pentru aceasta.
pentru a experimenta comportament, schimbarea pauzelor în generația de noi fire, numărul de fire, cantitatea de permisiuni sau timp aleator pentru sarcina codului.