Sincronización Pura en Java

Yo no soy muy de Java, pero estoy haciendo la una práctica sobre concurrencia en Java y bueno he tenido que recordar algunas cosas. Me he hecho una implementación de para la sincronización pura entre 2 hilos en Java.

Existen muchas variantes de la explicación del problema del consumidor / productor. Yo para probar la clase SincronizadorPuro he considerado el problema de la siguiente forma.

  • El consumidor va a consumir N veces
  • El productor va a producir N veces
  • Siempre lo deben hacer alternativamente

El recurso de lo que se consume o produce debe ser protegido, y por tanto realmente estamos hablando de comunicación sincronizada, pero realmente el problema que quiero abordar es el de la sincronización pura. Además que solucionar el problema de comunicación es tan simple como hacer sincronizados los metodos get / set del atributo a proteger.

El diagrama de precedencia sería:

A—-> B —-> A —-> B —- …..—->A ——> B

Este diagrama se resuelve con 2 semaforos iniciados a 0 con máximo 1. Que es lo que abstroigo en la clase SincronizacionPura con los métodos: esperar() / avisar() que corresponden al típico wait / signal de los semáforos.

Por ello el algoritmo para A es simplemente:

  • Esperará a B excepto si es la primera iteración.
  • Se ejecuta el código A, en mi ejemplo pone el contador del for en el recurso compartido.
  • Se avisa a B de que ha terminado.

Y analogamente, el algoritmo de B:

  • Primero esperará a A siempre.
  • Ejecuta el código asociado a B, que en mi caso es imprimir el valor del recurso.
  • Se avisa a A excepto en la última iteración.

Código del ejemplo:

package parquetematico;

import java.util.concurrent.Semaphore;

class Productor implements Runnable
{
    int INICIO;
    int FIN;
    int INC;
    Recurso recurso;
    SincronizadorPuro sync_productor;
    SincronizadorPuro sync_consumidor;

    public Productor(int INICIO, int FIN, int INC, Recurso recurso, SincronizadorPuro sync_productor, SincronizadorPuro sync_consumidor)
    {
        this.INICIO = INICIO;
        this.FIN = FIN;
        this.INC = INC;
        this.recurso = recurso;
        this.sync_productor = sync_productor;
        this.sync_consumidor = sync_consumidor;
    }

    public void run()
    {
        int i = INICIO;

        while (i <= FIN)
        {
            if(INICIO != i)
                sync_consumidor.esperar();

            recurso.setX(i);
            System.out.println("produce " + recurso.getX());

            sync_productor.avisar();

            i+=INC;
        }
    }

}

 class Consumidor implements Runnable
 {

    int INICIO;
    int FIN;
    int INC;
    Recurso recurso;
    SincronizadorPuro sync_productor;
    SincronizadorPuro sync_consumidor;

    public Consumidor(int INICIO, int FIN, int INC, Recurso recurso, SincronizadorPuro sync_productor, SincronizadorPuro sync_consumidor)
    {
        this.INICIO = INICIO;
        this.FIN = FIN;
        this.INC = INC;
        this.recurso = recurso;
        this.sync_productor = sync_productor;
        this.sync_consumidor = sync_consumidor;
    }

    public void run()
    {
        int i = INICIO;

        while (i <= FIN)
        {
            sync_productor.esperar();

            System.out.println("consume " + recurso.getX());

            if(FIN != i)
                sync_consumidor.avisar();

            i+=INC;
        }
    }

}

class SincronizadorPuro
{
    Semaphore sync;

    public SincronizadorPuro(int max) {
        // crea un semaforo en (max, max)
        sync = new Semaphore(max);

        // lo dejamos como (0, max)
        for(int i=0 ; i<max ; i++)
        {
            try {
            sync.acquire();
            } catch (InterruptedException e) {}
        }
    }

    /*
     * Pseudo-implementación conceptual
     *
    WAIT / P / ESPERAR / ACQUIRE
    {
        cont--;
        if (cont < 0)
        {
            while (true)
            {
                try
                {
                    wait();
                    break;
                }
                catch (InterruptedException e)
                {
                    if (cont >= 0)
                        break;
                    else
                        continue;
                }
            }
        }
    }
    */
    public void esperar()
    {
        try {
        sync.acquire();
        } catch (InterruptedException e) {}
    }

    /*
     * Pseudo-implementación conceptual
     *
    SIGNAL/ V / AVISAR / RELEASE
    {
        cont++;
        if (cont <= 0)
            notify();
        if (cont > 1)
            cont = 1;
    }
    */
    public void avisar()
    {
        sync.release();
    }

    public int getContador()
    {
        return sync.availablePermits();
    }
}

class Recurso
{
    private int x;

    public Recurso(int x)
    {
        this.x = x;
    }

    public synchronized void setX(int x)
    {
        this.x = x;
    }

    public synchronized int getX()
    {
        return x;
    }

}

public class principal
{

    public static void main(String[] args)
    {
        Recurso r1 = new Recurso(0);
        SincronizadorPuro sync_productor = new SincronizadorPuro(1);
        SincronizadorPuro sync_consumidor = new SincronizadorPuro(1);

        // produce/consume desde 0 hasta 5000 en pasos de 1
        Productor p1 = new Productor(0,5000, 1, r1, sync_productor, sync_consumidor);
        Consumidor c1 = new Consumidor(0,5000, 1, r1, sync_productor, sync_consumidor);
        Thread h1 = new Thread(p1);
        Thread h2 = new Thread(c1);
        h1.start();
        h2.start();
        try
        {
            h1.join();
            h2.join();
        }
        catch(InterruptedException e) {}
    }

}

Laberinto TD, ganador del MobiGame 2009 !!!

Este es el primer año que me presento al MobiGame e incluso que aprendo J2ME como ya dije en «Aprendiendo J2ME para el MobiGame«, aunque si que he trasteado mucho con J2SE (tengo un juego Java tipo Worms por hay subido que  hice con 14 tacos y ahora tengo 23).

Gracias al ejemplo de GameCanvas que viene con NetBeans no tardé ni un rato en tener una primera versión de un muñeco moviéndose por el escenario. Un mes después presente todo el análisis y diseño y alguna screen (solo había 1 tipo de torre y 1 tipo de enemigo en ese momento.)

Ha sido mi primer año y realmente me ha gustado mucho, ha habido muy buenos juegos y cualquiera podría haber ganado, estaba muy igualado. Os doy las gracias a todos los participantes por haber hecho que realmente haya competición. También gracias a la organización y todo el ambiente que han creado.

Seguir leyendo

Presentación de Laberinto Tower Defense

Llevo 4 fines de semana haciendo el desarrollo de Laberinto TD. Aunque el análisis y diseño es un trabajo de mucho tiempo (meses/años) de un juego que estaba haciendo (y cuando pueda lo seguiré) en c++.
El juego es una defensa de Torretas, como los custom maps del Warcraft3 y esta desarrollado más o menos al 50%:
Las caracteristicas del juego son las siguientes:

  1. Busqueda de caminos por los enemigos mediante IA, he implementado el algoritmo A*.
  2. 10 mapas, 50 niveles y 4 dificultades.
  3. Haré unos 10 tipos de torretas: hielo, splash, arrow, aura, aturdir, laser,veneno, invis, ultimate ….
  4. Cada tipo de torreta se podrá actualizar entre 5 y 20 levels.
  5. Todo se financiara con oro, la forma de obtenerlo es matando enemigos y consiguiendo hitos.
  6. Haré unas instrucciones de uso y ayudas en distintos menús de elección.
  7. Se guardarán persistentemente las máximas puntuaciones en cada mapa.
  8. Las condiciones de victoria es pasarte los 50 niveles.
  9. Las condiciones de derrota es no perder todas las vidas o alcanzar un número de máximo de enemigos.

Os pongo algunas imagenes:

Acepto cualquier sugerencia e idea. En mi opinión si consigo implementar todo lo que tengo pensado el juego puede ser un autentico vicio en esta o en cualquier plataforma. Espero que al menos os parezca interesante. Un saludo.

Aprendiendo J2ME para el MobiGame

Me voy a presentar el MobiGame (a punta de pistola por nuestro profe de informática distribuidda). Tengo poco tiempo asi además de enpoyarme el API de MIDP 2.0 aprovechare el análisis y diseño de mi maze tower hecho en una arquitectura muy distinta (pc, c++, physx , ogre …). Ya pondre algun post de mis avances. Mientras tanto usaré estos post para ir poniendo recursos que me parezcan interesantes.

Desde luego un torretas para movil sería algo muy novedoso en esta plataforma, y yo sería el primero que me estaría viciando por eso lo hago ;D

Español:

http://leo.ugr.es/J2ME/MIDP/index2.htm

http://www.it.uc3m.es/celeste/docencia/j2me/tutoriales/midp2_0/PracticaGame/

http://www.lcc.uma.es/~galvez/J2ME.html

Ingles:

http://wiki.netbeans.org/CreatingJavaMEGamesWithGameBuilder

http://today.java.net/pub/a/today/2005/02/09/j2me1.html

http://developers.sun.com/mobility/midp/articles/gameapi/

http://www.mcobject.com/perst_eval

Instalar Netbeans 6.0 en Ubuntu por repositorio

logoNBEste IDE es mi favorito para java cuando tengo que usar swing, he encontrado un repositorio para ubuntu gutsy, que nos evita instalar el binario de SUN. Para ellos procedemos a lo siguiente:

  • Añadimos el repositorio : echo deb http://srvremi.free.fr/ubuntu gutsy main | sudo tee -a /etc/apt/sources.list
  • Autententificamos el nuevo repositorio : gpg –keyserver wwwkeys.eu.pgp.net –recv-keys AA82C25A36399439
  • gpg –armor –export AA82C25A36399439 | sudo apt-key add –
  • Actualizamos : sudo apt-get update
  • Para una instalación básica de NetBeans 6.0 ponemos : sudo apt-get install netbeans6-base netbeans6-common netbeans6-j2ee netbeans6-java
  • Aqui pongo una lista del resto de paquetes que añaden funcionalidad a netbeans:
    • netbeans6-cpp – C/C++ (Prefiero eclipse + con plugins para soporte c++)
    • netbeans6-glassfish – GlassFish V2
    • netbeans6-ruby – Ruby
    • netbeans6-mobility – Mobility
    • netbeans6-openesb – Open ESB V2 Preview 3
    • netbeans6-soa – SOA
    • netbeans6-tomcat – GlassFish V2
    • netbeans6-uml – UML (lo use para una práctica de la universidad, me ahorro mucho tiempo)

Fuentes:
http://srvremi.free.fr/blog/2007/12/installer-netbeans-6-sur-ubuntu.html