Uso de "Threads" con sincronización

A continuación se describen una serie de Clases que hacen uso del concepto de Sincronización en "Threads" .

Código Fuente CampoDeTiro.java

 
 public class CampoDeTiro {
    public static void main(String[] args) {
        Pistola arma = new Pistola();
        Cargar c = new Cargar(arma, 1);
        Descargar d = new Descargar(arma, 1);
        c.start();
        d.start();
    }
 }

Código Fuente Pistola.java

 
public class Pistola {
    private int cartucho;
    private boolean enposicion = true;

    public synchronized void disparar(int cartucho) {
        while (enposicion == false) {
            try {
                // Esperar a apuntar
                wait();
            } catch (InterruptedException e) { }
        }
        enposicion = false;
        notifyAll();
    }
 
    public synchronized void apuntar() {
        while (enposicion == true) {
            try {
                // Esperar a disparar
                wait();
            } catch (InterruptedException e) { }
        }
        enposicion = true;
        notifyAll();
    }

}

Significado/Uso de synchronized

Cuando es empleado el vocablo synchronized se esta indicando una zona restringida para el uso de "Threads", esta zona restringida para efectos prácticos puede ser considerada un candado("lock") sobre la instancia del Objeto en cuestión.

Lo anterior implica que si es invocado un método synchronized únicamente el "Thread" que lo invoca tiene acceso a la instancia del Objeto, y cualquier otro "Thread" que intente accesar esta misma instancia tendrá que esperar hasta que sea terminada la ejecución del método synchronized.

Debido a que el uso de synchronized esta directamente relacionado con "Threads", dentro de este tipo de métodos también es posible definir otra serie de mecanismos que permiten una coordinación efectiva de "Threads", esta serie de mecanismos reside en los métodos wait, notify y notifyAll.

El método wait permite paralizar temporalmente la ejecución de un "Thread" bajo determinada circunstancia, mientras los métodos notify y notifyAll permiten enviar notificaciones individuales y a todo "Thread" respectivamente, sobre la terminación de un "Thread" especifico.

Codigo Fuente Cargar.java

 
public class Cargar extends Thread {
    private Pistola arma;
    private int cartucho;

    public Cargar(Pistola arma, int cartucho) {
        this.arma = arma;
        this.cartucho = cartucho;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            arma.apuntar();
            System.out.println("Apuntar #" + this.cartucho
                               + " bala: " + i);
        }
    }
}

Código Fuente Descargar.java

 
public class Descargar extends Thread {
    private Pistola arma;
    private int cartucho;

    public Descargar(Pistola arma, int cartucho) {
        this.arma = arma;
        this.cartucho = cartucho;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            arma.disparar(i);
            System.out.println("Descargar #" + this.cartucho
                               + " bala: " + i);
        }
    }
}

Resultados

Al ejecutar la Clase CampoDeTiro se estarían ejecutando dos "Threads" simultáneamente, sin embargo, a diferencia del ejemplo descrito anteriormente notará que el orden de ejecución será llevado acabo de manera ordenada, esto es, el resultado producido siempre será idéntico.

Lo anterior se debe al uso del vocablo synchronized y los diversos eventos disponibles para manipulación de "Threads" (notifyAll y wait).

Menú Curso

Objetos, Java y JDK

Composición, Clases y Librerías("Packages").

Variables, Constructores, Métodos y Comentarios.

Herencias ("Inheritance"), Condicionales y Ciclos

Operadores, Errores y Datos de Entrada/"Streams".

Interfases, Arreglos y Polimorfismo.

Collections Framework, "Threads", Garbage Collection y "Assertions".

Java 5 / JDK 5 .

Instalación Software.

Codigo.