Java: vectores dinámicos sincronizados

by Francho Joven

22 Apr 2009

. Comments

Este es un ejemplo que implementa un vector dinámico sincronizado programado en java (sin usar las clases que ya existen ya que se trata de un ejercicio ;-) )

Para probar su funcionamiento lanzaremos varios threads que intentarán añadir y borrar elementos al vector de forma simultanea.

Main.java

[java]
/*
* Crear una implementación sincronizada de un vector dinámico
*
* Métodos:
* - añadir(elemento)
* - añadirEn(elemento, posicion)
* - borrar(elemento)
* - borrar(posicion)
*/
package ejerciciovectordinamico;

/**
*
* @author: $Author: franchux $
* @version: $Rev: 100 $
* @date: $Date: 2009-04-21 09:38:58 +0200 (mar 21 de abr de 2009) $
* $Id: Main.java 100 2009-04-21 07:38:58Z franchux $
*/
public class Main
{

public static final int HILOS = 8;

/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
VectorDinamicoSincronizado vector = new VectorDinamicoSincronizado();

// Este array nos permitirá controlar los hilos que creemos
//Thread[] manejador = new Thread[HILOS];

// Creamos los hilos que intentarán modificar posiciones del vector con valores aleatorios
for (int i = 0; i < HILOS; i++) {
TestVectorDinamicoRunnable r = new TestVectorDinamicoRunnable(vector);
Thread t = new Thread(r);
t.start();
//manejador[i] = new Thread(r);
//manejador[i].start();
}

// Ahora llenamos el vector para que los hilos que puedan los sobreescriban
for (int i = 0; i < HILOS; i++) {
vector.añadir("-");
}

// Damos un tiempo para que los hilos intenten hacer su trabajo
espera(5000);

// Cerramos los hilos que quedan abiertos
int numActivas = Thread.activeCount();
Thread[] manejador = new Thread[numActivas];
Thread.enumerate(manejador);
for (Thread t : manejador) {
if (t.isAlive()) {
t.interrupt();
}
}

System.out.println(vector);

System.out.println("Hilo principal terminado");

}

public static void espera(int milisegundos)
{

long t0, t1;

t0 = System.currentTimeMillis();
do {
t1 = System.currentTimeMillis();
} while (t1 - t0 < milisegundos);
}
}
[/java]

VectorDinamicoSincronizado.java

[java]
package ejerciciovectordinamico;

/**
*
* @author: $Author: franchux $
* @version: $Rev: 100 $
* @date: $Date: 2009-04-21 09:38:58 +0200 (mar 21 de abr de 2009) $
* $Id: VectorDinamicoSincronizado.java 100 2009-04-21 07:38:58Z franchux $
*/
public class VectorDinamicoSincronizado {

protected String[] datos;
final static int TIMEOUT = 1000;

public VectorDinamicoSincronizado() {
datos = new String[0];
}

/**
* Añade un número al final de la lista
*
* @param numero a insertar
*/
public void añadir(String texto) {
//insertarOrdenado(numero);
String[] nuevo = new String[datos.length + 1];
for (int i = 0; i < datos.length; i++) {
nuevo[i] = datos[i];
}
nuevo[datos.length] = texto;
datos = nuevo;
loguea("pongo " + texto + " al final");
}

/**
* Añade una cadena en una determinada posicion
*
* @param texto a añadir
* @param posicion posición donde colocarlo
*/
public synchronized void añadirEn(String texto, int posicion) {

try { // Si la posición que intentamos insertar está fuera del vector actual
// Esperamos a ver si hay suerte y el vector crece
while(posicion > (datos.length - 1)) {
loguea("no puedo insertar " + texto + " en posicion " + posicion + " espero...");
wait(TIMEOUT);
}
datos[posicion] = texto;
loguea("pongo " + texto + " en " + posicion);

} catch (InterruptedException ex) {
// Logger.getLogger(VectorDinamicoSincronizado.class.getName()).log(Level.SEVERE, null, ex);
loguea("HILO TERMINADO: no puedo insertar " + texto + " en posicion " + posicion + " abandono");
}

notifyAll();
}

public synchronized void borrar(int posicion) {
String [] nueva = new String[datos.length -1];
int n=0;

for(int i=0;i<datos.length;i++) {
if(i!=posicion) {
nueva[n++] = datos[i];
}
}

datos = nueva;
}

/**
* Muestra por pantalla un mensaje de debug
*
* @param texto a mostrar
*/
public void loguea(String texto) {
System.out.println(Thread.currentThread().toString() + texto);
}

/**
* Maqueta el contenido
*
* @return cadena con todos los numeros del array
*/
@Override
public String toString() {
String cad = "[ ";
for (String d : datos) {
cad += "" + d + " ";
}
cad += "]";

return cad;
}
}
[/java]

TestVectorDinamicoSincronizadoRunnable.java

[java]
package ejerciciovectordinamico;

/**
*
* @author: $Author: franchux $
* @version: $Rev: 99 $
* @date: $Date: 2009-04-21 00:49:25 +0200 (mar 21 de abr de 2009) $
* $Id: TestVectorDinamicoRunnable.java 99 2009-04-20 22:49:25Z franchux $
*/
public class TestVectorDinamicoRunnable implements Runnable {

VectorDinamicoSincronizado vector;

public TestVectorDinamicoRunnable(VectorDinamicoSincronizado vector) {
this.vector = vector;
}

public void run()
{
int num = (int) (Math.random() * 10);
int pos;
do {
pos = (int) (Math.random() * 10) - 1;
} while(pos < 0);

vector.añadirEn(""+num, pos);

// vector.borrar((int)Math.random());
System.out.println(Thread.currentThread() + ": " + vector.toString());
}
}
[/java]