Ejemplos de comunicación y sincronización de hilos

Cómo comunicar y sincronizar hilos que acceden a un recurso común.

Código con los ejemplos del libro

Comunicación y sincronización de hilos

Recursos del capítulo 2: Programación multihilo

CompartirInf1.java

class Contador {
    private int c = 0;
    Contador(int c) {
        this.c = c;
    }

    public void incrementa() {
        c = c + 1;
    }

    public void decrementa() {
        c = c - 1;
    }

    public int getValor() {
        return c;
    }

}// CONTADOR

class HiloA extends Thread {
    private Contador contador;
    public HiloA(String n, Contador c) {
        setName(n);
        contador = c;
    }
    public void run() {
        for (int j = 0; j < 300; j++) {
            contador.incrementa();
            /*try {
                sleep(100);
            } catch (InterruptedException e) {		}*/
        }
        System.out.println(getName() + " contador vale " + contador.getValor());
    }
}// FIN HILO A

class HiloB extends Thread {
    private Contador contador;
    public HiloB(String n, Contador c) {
        setName(n);
        contador = c;
    }
    public void run() {
        for (int j = 0; j < 300; j++) {
            contador.decrementa();
            /*try {
                sleep(100);
            } catch (InterruptedException e) {}*/
        }
        System.out.println(getName() + " contador vale " + contador.getValor());
    }
}// FIN HILO B

public class CompartirInf1 {
    public static void main(String[] args) {
        Contador cont = new Contador(100);
        HiloA a = new HiloA("HiloA", cont);
        HiloB b = new HiloB("HiloB", cont);
        a.start();
        b.start();       
    }
}

Bloques sincronizados

CompartirInf2.java

class Contador2 {
    private int c = 0;

    Contador2(int c) {
        this.c = c;
    }

    public void incrementa() {
        c = c + 1;
    }

    public void decrementa() {
        c = c - 1;
    }

    public int getValor() {
        return c;
    }

}// CONTADOR

class HiloA2 extends Thread {
    private Contador2 contador;

    public HiloA2(String n, Contador2 c) {
        setName(n);
        contador = c;
    }

    public void run() {
        synchronized (contador) {
            for (int j = 0; j < 300; j++) {
                contador.incrementa();
                /*try {
                    sleep(100);
                } catch (InterruptedException e) {		}
                */
            }
            System.out.println(getName() + " contador vale "
                    + contador.getValor());
        }

    }
}// HILO A

class HiloB2 extends Thread {
    private Contador2 contador;

    public HiloB2(String n, Contador2 c) {
        setName(n);
        contador = c;
    }

    public void run() {
        synchronized (contador) {
            for (int j = 0; j < 300; j++) {
                contador.decrementa();
                /*try {
                    sleep(100);
                } catch (InterruptedException e) {		}
                */
            }
            System.out.println(getName() + " contador vale "
                    + contador.getValor());
        }
    }
}// HILO B

public class CompartirInf2 {
    public static void main(String[] args) {
        Contador2 cont = new Contador2(100);
        HiloA2 a = new HiloA2("HiloA", cont);
        HiloB2 b = new HiloB2("HiloB", cont);
        a.start();		
        b.start();
        
    }
}

Métodos sincronizados

CompartirInf3.java

class Cuenta {
    private int saldo ;
    Cuenta (int s) {saldo = s;}
    
    int getSaldo() {return saldo;}
    void restar(int cantidad){saldo=saldo-cantidad;}
    
    void RetirarDinero(int cant, String nom) {	
        if (getSaldo() >= cant) {
            System.out.println(nom+": SE VA A RETIRAR SALDO (ACTUAL ES: "+getSaldo()+ ")" );
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {	}
            
            restar(cant);	
            
            System.out.println("\t"+nom+ " retira =>"+cant + " ACTUAL("+getSaldo()+")" );	
        } else {
            System.out.println(nom+ " No puede retirar dinero, NO HAY SALDO("+getSaldo()+")" );
        }
        if (getSaldo() < 0) {
            System.out.println("SALDO NEGATIVO => "+getSaldo());
        }		
    }//retirar
}

class SacarDinero extends Thread {
    private Cuenta c;	
    public SacarDinero(String n, Cuenta c) {		
        super(n);
        this.c = c;
    }
    public  void run() {		
        for (int x = 1; x<= 4; x++) {		
            c.RetirarDinero(10, getName());
            try { 
                Thread.sleep(1000); 
            } catch (InterruptedException ex) { }		
        }		
    }// run	
}

public class CompartirInf3 {
    public static void main(String[] args) {
        Cuenta c = new Cuenta(40);
        SacarDinero h1 = new SacarDinero("Ana", c);
        SacarDinero h2 = new SacarDinero("Juan", c);

        h1.start();
        h2.start();
    }
}

CompartirInf4.java

synchronized void RetirarDinero(int cant, String nom)

class Cuenta2 {
    private int saldo ;
    Cuenta2 (int s) { saldo = s; }
    
    int getSaldo() { return saldo; }
    void restar(int cantidad) { saldo=saldo-cantidad; }
    
    synchronized void RetirarDinero(int cant, String nom) {
        if (getSaldo() >= cant) {
            System.out.println(nom+": SE VA A RETIRAR SALDO (ACTUAL ES: "+getSaldo()+ ")" );
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {	}
            
            restar(cant);		
            
            System.out.println("\t"+ nom+ " retira =>"+cant + " ACTUAL("+getSaldo()+")" );	
        } else {
            System.out.println(nom+ " No puede retirar dinero, NO HAY SALDO("+getSaldo()+")" );
        }
        if (getSaldo() < 0) {
            System.out.println("SALDO NEGATIVO => "+getSaldo());
        }
        
    }//retirar
}

class SacarDinero2 extends Thread {
    private Cuenta2 c;
    String nom;
    public SacarDinero2(String n, Cuenta2 c) {		
        super(n);
        this.c = c;
    }
    public  void run() {		
        for (int x = 1; x<= 4; x++) {		
            c.RetirarDinero(10, getName());			
        }		
    }// run
    
}
public class CompartirInf4 {
    public static void main(String[] fer) {
        Cuenta2 c = new Cuenta2(40);
        SacarDinero2 h1 = new SacarDinero2("Ana", c);
        SacarDinero2 h2 = new SacarDinero2("Juan", c);

        h1.start();
        h2.start();
    }
}

 

Ejercicio 3 de la tarea online

 

Ejemplo de los filósofos

Problema de los filósofos

Una solución gráfica: La cena de los filósofos

https://github.com/PacoPortillo/DAM_PSP_Tarea02_La-Cena-de-los-Filosofos/blob/master/dist/LaCenaFilosofos.jar
java -jar "LaCenaFilosofos.jar"

Otra solución gráfica: problema de los filósofos

wget https://github.com/OdeiRZ/Filosofos_Comensales/blob/master/dist/Filosofos_Comensales.jar
java -jar "Filosofos_Comensales.jar"

Ejercicio 4 de la tarea online

Más información:

Hacer ficheros jar

Package an application into a JAR in IntelliJ IDEA

Deja una respuesta