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) {}
    }

}

Por fin termina el curso

En poco más de 2 horas tengo el último examen … (Aunque me queda una práctica sobre concurrencia para el día 25.)

El caso, es que ha sido un gran año(a costa de bajar la los posteos del blog y no tener nunca tiempo …), y prácticamente no me queda nada para acabar la carrera el año que viene. En el primer cuatrimestre solo me matricularé a 2 asignaturas !. En el segundo habrá que esperar a las notas, pero calculo que unas 6 asignaturas. Lo que me deja un año bastante sabático para centrarme en el PFC.

Me he matriculado a 2 curos de verano, que organiza la universidad:

El segundo curso, me he matriculado porque precisamente sobre algo parecido a eso, quiero dedicar mi PFC.  Todavía no tengo un profesor, ni he hecho el anteproyecto, pero me pondré a ello en el mes de julio. Pero ya tengo mucho código escrito, y muchas ideas pensadas.

El PFC me gustaría hablar sobre la arquitectura de los juegos. Me gustaría hacerlo en 2 partes: Una parte densa teórica. Y una implementación práctica.

Voy a comprar unos cuantos libros por amazon, y sobre todo estudiar el código de John Carmack (quake 1,2 y III). Como gran referente y pionero en crear buenas arquitecturas en los juegos.

El PFC es bastante ambicioso por lo que no descarto, hacer un PFC más modesto, y postponerlo para el Grado de Ingeniería Informática. Ya que cuando acabe me gustaría convalidar con GII y hacer 2 años más. Para entonces habré aprendido más sobre IA, y otros temas, y estaré más preparado que ahora.

Cambiando de tercio, he recibido ya un total de 25€ (restar las tarifas de paypal) en donaciones (de españoles 0€, ojo al dato) para el proyecto Wiithon, por lo que me siento un poco en deuda. Además que utilizando Wiithon como usuario, todavía se pueden mejorar algunas cosas. Como probar que tal funcionaría con una SGBD decente, en lugar de sqlite. En mi caso, tengo más de 600 juegos de Wii y aunque va muy rápido, en ordenadores de +4 años, se nota que sqlite se queda corto.

Bueno, me voy al examen, que le pedido salir al jefe antes : D

Eclipse instalando el plugin de Android (ADT) en Linux

Si habeis instalado Eclipse mediante el Centro de Software Ubuntu, puede que tengais problemas siguiendo el procediemiento que explica Google.

Por tanto, probar hacerlo mejor así:

  1. Se supone que ya teneis instalado el paquete eclipse, instalar además el paquete: sudo apt-get install eclipse-jdt eclipse-pde , tal y como explica el Bug #477944 (aunque esta un poco caótico).
  2. Ahora debeis ejecutar Eclipse y en Help -> Install new software, debeis añadir estos 2 sitios:
  3. Ahora simplemente instalais “Developers Tools”, que activará automaticmante “Android DDMS” y “Android Development Tools”. Tendreis que aceptar todas las licencias que corresponda.
  4. Fin, ya podemos crear un proyecto. Tengo pensado publicar un trabajo que estoy haciendo de Android y explicar un poco hacer un HolaMundo en cuanto tenga tiempo.

Espero que le sea útil a alguien. Un saludo

Fuentes:
http://developer.android.com/sdk/eclipse-adt.html
https://bugs.launchpad.net/ubuntu/+source/eclipse/+bug/482244
https://bugs.launchpad.net/ubuntu/+source/eclipse/+bug/477944

Pokemon Real

Llevo sin jugar al pokemon, desde que tenía la game boy gorda, la que venía con el tetris xD. Ya entonces me envicio exagerado, solo me falto el mewtwo de los cojones xDD y el mew que decian que no se podía capturar.

A mi novia le han regalado la ds con 2 juegos de pokemon, hemos empezado a jugar al diamante y joder, es buenisimo xD Tambien es verdad que no tenemos la ds pirateada -_- ….

En relación, os dejo con un video buenisimo y subtitulado:

Habrá Steam para Linux

Hace unos días, Valve ha lanzado la versión de Mac de Steam por todo lo alto, acompañado de ofertas y regalando el Portal.

En un artículo en el Telegraph se ha dicho:
“Valve has also confirmed that it will make Steam available to Linux users in the coming months.”

Cada vez siento que estamos más cerca de un mercado multiplataforma … pero todavía falta mucho, lo que esta claro es que es un paso importante para el Gaming.

En cuanto al rendimeinto, si Valve ha llevado sus juegos a Mac, que es una plataforma prima respecto a Linux (pero con un rendimiento bastante menor que en Linux como se demuestra en esta benchmark). Tras esta confirmación, Linux ofrece un rendimiento muy ligeramente inferior a windows actualmente, (principalmente por la calidad de los drivers).

Todos estos temas se debaten en este articulo, y llegan a la conclusión de que esta noticia puede representar toda una revolución para el mercado de los videojuegos en Linux:
http://www.phoronix.com/scan.php?page=article&item=valve_steam_announcement&num=1

Ahora solo falta pedir que su cliente  se licencie como GPL, lo cual, conociendo a Valve es casi imposible. Un saludo.

P.D: Me gustaría escribir más, pero este año estoy concentrado en la uni y he abandonado más de lo que me gustaría el wiithon y el blog. ¡¡ Quiero terminar el cuatrimestre !!

Fuentes:
http://www.telegraph.co.uk/technology/apple/7715209/Steam-for-Mac-goes-live.html
http://www.muylinux.com/2010/05/12/ya-es-oficial-%C2%A1steam-estara-disponible-en-linux

Timofonica pasa a ser Vomistar

Pues si, estos señores creen que cambiando de nombre, su imagen va a mejorar en algo. Exactamente no sabemos el motivo del cambio …

Telefonica ha conseguido introducirse en muchos paises conocido como movistar, ya que solo daban cobertura movil, posiblemente ese sea el principal motivo.

Hay otras teorías más conspiradoras sobre evasión de impuestos o por temas legales.

Tambien puede haber hecho mella el video en el que sale el presidente de Telefonica medio pedo diciendo gilipolleces sin parar. ( https://blogricardo.wordpress.com/2010/02/28/ganas-de-matar-aumentando/ )

En fin, para mi siempre será Timofonica, esa multinacional que todo el mundo odia, snif snif :(

Cliente VNC no refresca

Hoy me ha ocurrido un efecto curioso. Conectaba al portatil de mi casa por VNC y solo me mostraba el primer pantallazo inicial, no refrescaba nada …

Volví a casa y haciendo pruebas vi que me ocurre desde que active el compiz (solo lo utilizo por el scale). Entonces la solución aunque no es la mejor, es buena, desactivar el composite/compiz.

Por cierto si vais mal de subida, el visor de escritorio remoto va a Full Color y realmente se toma su tiempo cada frame. Instalar “xvnc4viewer”, y simplemente con “vncviewer xx.xx.xx.xx” conectamos en 8 bits, funciona muy fluido, y para administración es más que suficiente. No obstante si quereis 24 bits (Full Color) añadir el parametro “-FullColor”.