Examen Programación Hilos - HinchaGlobos y PinchaGlobos

Examen Programación Hilos - HinchaGlobos y PinchaGlobos

Recientemente acabo de terminar mis exámenes de programación, y en este caso me gustaría compartir con vosotros el examen de programación de servicios y procesos.

El lenguaje de programación que se ha utilizado para resolver el ejercicio es Java, y el examen decía lo siguiente (Dejo la nota de cada punto por si queréis intentarlo vosotros y calcular cual sería vuestra nota):

Examen Programación Servicios y Procesos

Hacer un programa compuesto por cuatro clases:
• Clases hilos HinchaGlobos (HG) (encargada de hinchar los globos)
• Clase hilo PinchaGlobos (PG) (encargada de pinchar los globos)
• Clase Globos (almacén de globos)
• Clase Inicio (contiene el código main e instancia al resto)

En relación a la clase Globos (tendremos 1 instancia de esta clase)
• En el almacén habrá un máximo de 10 globos .
• Se irán entregando de uno en uno numerándolos desde 1 a 10.
• Una vez entregados se podrán hinchar hasta que estallen o los pinchen.
• Sólo podrá haber 3 globos hinchándose a la vez.
• Los globos tendrán volumen de 1 a 5. Si se llena más de 5 estallan.
• El globo se entrega con un volumen inicial de l.
• Los globos pueden ser pinchados mientras se están hinchando.
• Se escribirá un mensaje con el número de globo cada vez que:
o Se entregue un globo (indicaremos el nombre del hilo ejem: GLOBO 5 ENTREGADO A HG3) o Se hinche un globo e indicaremos el nuevo volumen (ejem: GLOBO 5 VOLUMEN 5)
o Se estalle un globo por inflar de más (ejem : GLOBO 5 ESTALLA)
o Un PG pinche un globo (indicaremos el nombre del hilo ejem : GLOBO 5 PINCHADO POR PG3)

En relación a la clase HinchaGlobos (tendremos 5 instancias de esta clase)
• (0,5) Obtendrá un globo de la clase globos cada vez y en orden salvo que no queden más.
• (2) Si ya hubiera tres hinchándose se esperará hasta que uno se pinche o estalle .
• Los tendremos que numerar y nombrar con HG seguido de su número. (ejem: HG3)
• (1) Intentará hincharlo hasta estallarlo salvo que sea pinchando.
• (1) Cada segundo aumentará el volumen del globo desde 1 hasta estallarlo.
• (1) Si estalla o se pincha volverá a por otro globo hasta que no queden más.

En relación a la clase PinchaGlobos (tendremos 5 instancias de esta clase)
• (1) Intentará pinchar uno de los globos que se está hinchando cada un tiempo aleatorio de 1 a 10 segundos .
• (1) Si no hay globos que pinchar se quedará en espera.
• (0,5) Dejará de pinchar cuando no queden globos que pinchar.
• Sus instancias las tendremos que numerar y nombrar con PG seguida de su número (ejem : PG 2)

Los distintos apartados serán comprobados por la impresión de los mensajes detallados en la clase Globos .

Se deberá tener en cuenta que aquellos dormidos deberán ser despertados convenientemente:
(1) Caso de HG dormidos
(1) Caso de PG dormidos

A continuación adjunto las 4 clases, lo que sería el examen perfecto con nota de 10, he intentado comentar todo para que podáis seguir el examen, si no entendéis algo lo modificaré.

1 - Clase Inicio (Main)

public class Inicio {
 
    public static void main(String[] args) {
 
        Globos g = new Globos();    //Instanciamos Globos
 
        for (int i=1;i<=5;i++) new HinchaGlobo(g,i);    //Bucle que crea 5 hilos de HinchaGlobo, le pasamos los globos e i para saber el número del hilo
        for (int i=1;i<=5;i++) new PinchaGlobo(g,i);    //Bucle que crea 5 hilos de PinchaGlobo, le pasamos los globos e i para saber el número del hilo
    }
}

2 - Clase Globos (Almacén de globos y los métodos)

public class Globos {
 
    private int maxHinchando=3;     // Número máximo de globos hinchando a la vez
    private int maxGlobos=10;        // Número máximo de globos en el almacén
    private int maxVolumen=5;          // Volumen máximo del globo
    private int nGlobo=1;             // Número del globo para dar, inicialmente 1
    private int hinchandoAhora=0;     // Cuántos se están hinchando ahora mismo
    private int globos[];
    // Si vale 0 el globo no está dado
    // Si vale 1 a maxVolumen está dado e indica su volumen
    // Si vale maxVolumen+1 está roto
    // Si vale maxVolumen+2 está pinchado
 
    public Globos() {    // Constructor de Globos
        globos=new int[maxGlobos];
        for (int i=0;i<maxGlobos;i++) globos[i]=0; // Rellenamos el almacén a 0, (ninguno dado).
    } 
 
    public synchronized int dameGlobo() { // Método que devuelve el siguiente globo del almacen, si no quedan devuelve -1
 
        while (hinchandoAhora==maxHinchando && nGlobo!=maxGlobos+1)  { // Me espero si ya hay maxHinchando y quedan globos por dar
            try {wait();} catch (Exception e) {}
        }
 
        if (nGlobo==maxGlobos+1) return -1; // Retorno un -1 si no quedan globos por dar
        globos[nGlobo-1]=1;                 // Cambio el 0 del almacen de globos por 1 (entregado a HinchaGlobos)
        System.out.println("GLOBO "+nGlobo+" ENTREGADO A "+Thread.currentThread().getName());    //Informo por consola a que hilo se le da el globo
        hinchandoAhora++;     //Sumo 1 al hinchaAhora
        notifyAll();        //Notifico a todos que hay un cambio
        return nGlobo++;    //Retorno el globo
    }
 
    public synchronized boolean pincho() { // Método que pincha un globo, si no quedan devuelve true
 
        while (hinchandoAhora==0 && nGlobo!=maxGlobos+1){    // Me espero si no hay hinchando y quedan por pinchar
            try {wait();} catch (Exception e) {}
        }
 
        if (nGlobo==maxGlobos+1) return true;    // Me aseguro de salir porque ha cambiado hinchando
 
        for (int i=0;i<maxGlobos;i++)    // Busco un globo para pinchar dentro del almacen
            if (globos[i]>0 && globos[i]<=maxVolumen) {
                System.out.println("GLOBO"+(i+1)+" LO PINCHA "+Thread.currentThread().getName());
                globos[i]=maxVolumen+2;
                hinchandoAhora--;
                notifyAll();
                break;
            }
 
        return hinchandoAhora!=0;
    }
 
    public synchronized boolean hincho(int num) {
 
        if (globos[num-1]<=maxVolumen) globos[num-1]++;    // Puede que ya esté estallado, se comprueba
        else return true;                                // si estuviera estallado, pinchado o estallase dev true
 
        if (globos[num-1]==maxVolumen+1){    // Si lo he estallado lo notifico
            hinchandoAhora--;
            System.out.println("GLOBO "+num+ " ESTALLA");
            notifyAll();
            return true;
        }
        else {
            System.out.println("GLOBO "+num+" VOLUMEN "+globos[num-1]);
            return false;
        }
    }
}

3 - Clase HinchaGlobo

public class HinchaGlobo extends Thread {
    //Los globos estallan cuando pasan de 10
    private Globos g;
    private int numero;
 
    public HinchaGlobo(Globos pg,int pnumero) {
        g=pg;
        numero=pnumero;
        setName("HG"+numero);
        start();
    }
 
    @Override
    public void run(){
        int manejado;
        boolean estalla; // cierto si se pincha o estalla
 
        while (true) {
            if ((manejado=g.dameGlobo())==-1) break ; // me da un globo o -1 si no hay mas
            do{
                try {Thread.sleep(1000);} catch (Exception e) {}
                estalla=g.hincho(manejado);
            } while (!estalla);  
 
        } // while(true)
    } // public run
} // public class

4 - Clase PinchaGlobo

public class PinchaGlobo extends Thread{
    private Globos g;
    private int numero;
    public PinchaGlobo(Globos pg,int pnumero){
        g=pg;
        numero=pnumero;
        setName("PG"+numero);
        start();
    }
 
    @Override
    public void run(){
        int num;
        boolean nohaymas;
        do{
            try {Thread.sleep((int)(Math.random()*5000));} catch (Exception e) {}
            // Si no quedan globos tengo que dejar de pinchar
            nohaymas=g.pincho();
        } while (!nohaymas); // while true
    } // public run
} // public class

¿Que nota has sacado?

Hasta aquí la entrada, no dudes en publicar tu nota.