Semàfors en Java

Aquí et deixo un exemple per al model usant un semàfor:

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

Amb la classe Hilo declarat com a classe interna no és necessari de explícitament passar la referència a Tuberia perquè té accés als mètodes de la classe pare.

el comptador està inclòs en blocs curts sincronitzats per garantir que els esdeveniments s’imprimeixen en la seqüència que ocorren.

el semàfor en l’exemple limita la quantitat de fils que tenen accés a el codi entre acquire i release.

La diferència principal entre les dues implementacions és que amb el semàfor hi ha una quantitat de fils que poden accedir a el codi en forma concurrent mentre el mètode sincronitzat garanteix que només un bri alhora pot accedir aquest bloc de codi, fent una acció atòmica.

Si això tie ne o no un sentit no és visible en un exemple tan bàsic, sense pensar que realment és la feina que fan els fils i que els recursos que necessiten per a això.

Per experimentar amb el comportament, canvia les pauses en generació de noves fibres, la quantitat de fibres, la quantitat dels permisos o el temps aleatori per a la càrrega de el codi.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *