¿Qué opináis sobre nuestro amigo "static"?
Independientemente de las discrepancias que cada uno pueda tener con esta declaración, me encuentro en el siguiente caso:
Si habéis tratado con Java Concurrente, seguramente sabréis que es muy usual utilizar el ejemplo del "Cocinero y Cliente"/"Productor y consumidor", etc. para ejemplificar el uso práctico de la concurrencia en Java.
El siguiente código que voy a mostraros ahora utiliza la variable entera static "tarta" y un 'lock' para el bloque synchronized también static. Creo que la pregunta es evidente, ¿si el uso de "static" es, supuestamente, y para algunos, una mala práctica, cómo podríamos resola declaración static?una forma alternativa a usar la declaración static?
Código:
/*
CONSUMIDOR:
- Si hay tarta = Me como una
- Si NO ... = Despertar COCINERO, dormir CONSUMIDOR.
COCINERO:
- Me duermo esperando a que un cliente me llame
- Si me llama produzco 10 trozos de tarta, me duermo.
*/
public class Principal implements Runnable {
private boolean consumidor;
private static int tarta=0;
private static Object lock = new Object();
public Principal(boolean consumidor) {
this.consumidor=consumidor;
}
public void run() {
while(true) {
if(consumidor) {
consumir();
}else {
cocinar();
}
}
}
private void consumir() {
synchronized(lock) { //Cerrojo
if(tarta>0) { //SI QUEDAN TARTAS...
tarta--; //Comer una tarta
System.out.println("Quedan "+tarta+" porciones de tarta.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else { //SI NO QUEDAN TARTAS...
lock.notifyAll(); //Despertar a el COCINERO que esperaba (abrir cerrojo, dejar pasar)
try {
lock.wait(); //Dormir al consumidor (hasta que lo despierten)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void cocinar() {
synchronized (lock) {
if(tarta==0) {
tarta=10; //Cocinar 10 trozos de tarta
System.out.println("Soy el cocinero y quedan "+tarta+" trozos.");
lock.notifyAll(); //"¡Chacho! Que las tartas están listas!", Vale tío.
} try {
lock.wait(); //dormir
}catch(Exception e) {}
}
}
public static void main(String[] args) {
int numHilos = 11;
Thread[] hilo = new Thread[numHilos];
for(int i=0; i<hilo.length; i++) {
Runnable runnable = null;
if(i !=0) {
runnable = new Principal(true);
}else {
runnable = new Principal(false);
}
hilo[i] = new Thread(runnable);
hilo[i].start();
}
for(int i=0; i<hilo.length; i++) {
try {
hilo[i].join();
}catch(Exception e) {}
}
}
}