lunes
jul142014
Duda sobre ArrayList y Vector.
Duda sobre ArrayList y Vector.
Buenos dís. Pensaba que tanto Vector como ArrayList se diferenciaban en que sus métodos eran (o no eran) thread-safe. Salió el debate en mi trabajo, y quise comprobarlo por mi mismo. Desarrollé el siguiente código. ¿Alguien puede indicarme la salida del mismo e intentar explicar la diferencia real, en un ejemplo práctico, entre Vector y ArrayList? Muchas gracias
01.
import
java.util.ArrayList;
02.
import
java.util.List;
03.
04.
public
class
Principal
implements
Runnable {
05.
06.
private
List<string> lista =
new
ArrayList<string>();
07.
private
static
List<principal> hilos =
new
ArrayList<principal>();
08.
09.
private
int
i =
0
;
10.
11.
private
final
int
MAX_VAL =
1000
;
12.
private
final
static
int
MAX_VAL_STATIC =
1000
;
13.
private
final
static
int
MAX_HILOS =
1000
;
14.
private
final
static
int
TIEMPO_ESPERA_MS =
1000
;
15.
16.
public
Principal(List<string> lista) {
17.
this
.lista = lista;
18.
19.
}
20.
21.
public
static
void
main(String[] args)
throws
InterruptedException {
22.
23.
Long inicio = System.currentTimeMillis();
24.
25.
List<string> lista =
new
ArrayList<string>();
26.
27.
System.out.println(
"Iniciando hilos...."
);
28.
for
(
int
i =
0
; i < MAX_HILOS; i++) {
29.
Principal p =
new
Principal(lista);
30.
hilos.add(p);
31.
}
32.
33.
System.out.println(
"OK"
);
34.
35.
System.out.println(
"Ejecutando hilos...."
);
36.
for
(Principal hilo : hilos) {
37.
hilo.run();
38.
}
39.
System.out.println(
"OK"
);
40.
41.
System.out.println(
"Esperando finalización"
);
42.
43.
boolean
finalizado =
true
;
44.
do
{
45.
Thread.sleep(TIEMPO_ESPERA_MS);
46.
47.
for
(Principal hilo : hilos) {
48.
if
(hilo.i < MAX_VAL_STATIC) {
49.
finalizado =
false
;
50.
}
51.
}
52.
53.
}
while
(!finalizado);
54.
55.
System.out.println(
"OK"
);
56.
57.
System.out.println(
"EL TAMAÑO DE LA LISTA ES: "
+ lista.size());
58.
Long total = System.currentTimeMillis() - inicio;
59.
}
60.
61.
public
int
getI() {
62.
return
i;
63.
}
64.
65.
public
void
setI(
int
i) {
66.
this
.i = i;
67.
}
68.
69.
@Override
70.
public
void
run() {
71.
while
(i < MAX_VAL) {
72.
lista.add(
""
+ i);
73.
i++;
74.
}
75.
}
76.
77.
}
78.
79.
</string></string></string></principal></principal></string></string>
Reader Comments (4)
Guenas.
Hay mas de un fallo en este código.
Sin mirarlo demasiado se ve que defines List<principal> cuando debería ser List<Principal>
Por otra parte realmente no estas usando hilos ya que ejecutas directamente run() y por tanto todo el proceso dentro del bucle se ejecuta secuencialmente, no en paralelo.
Un saludo
Muy bien visto,
El código bien desarrollado (utilizando Vector) sería:
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public class Principal extends Thread {
private List<String> lista = new Vector<String>();
private static List<Principal> hilos = new Vector<Principal>();
private int i = 0;
private final int MAX_VAL = 1000;
private final static int MAX_VAL_STATIC = 10;
private final static int MAX_HILOS = 10;
private final static int TIEMPO_ESPERA_MS = 1000;
public Principal(List<String> lista) {
this.lista = lista;
}
public static void main(String[] args) throws InterruptedException {
Long inicio = System.currentTimeMillis();
List<String> lista = new Vector<String>();
System.out.println("Iniciando hilos....");
for (int i = 0; i < MAX_HILOS; i++) {
Principal p = new Principal(lista);
hilos.add(p);
}
System.out.println("OK");
System.out.println("Ejecutando hilos....");
for (Principal hilo : hilos) {
hilo.start();
}
System.out.println("OK");
System.out.println("Esperando finalización");
boolean finalizado = true;
do {
Thread.sleep(TIEMPO_ESPERA_MS);
for (Principal hilo : hilos) {
if (hilo.i < MAX_VAL_STATIC) {
finalizado = false;
}
}
} while (!finalizado);
System.out.println("OK");
System.out.println("EL TAMAÑO DE LA LISTA ES: " + lista.size());
Long total = System.currentTimeMillis() - inicio;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
@Override
public void run() {
while (i < MAX_VAL) {
lista.add("" + i);
i++;
}
}
}
La ejecución del mismo da por pantalla:
Iniciando hilos....
OK
Ejecutando hilos....
OK
Esperando finalización
OK
EL TAMAÑO DE LA LISTA ES: 10000
Mientras que si hacemos uso de listas, vemos la siguiente salida por consola.
Iniciando hilos....
OK
Ejecutando hilos....
OK
Esperando finalización
Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 120
at java.util.ArrayList.add(Unknown Source)
at Principal.run(Principal.java:73)
Exception in thread "Thread-3" java.lang.ArrayIndexOutOfBoundsException: 607
at java.util.ArrayList.add(Unknown Source)
at Principal.run(Principal.java:73)
Exception in thread "Thread-4" java.lang.ArrayIndexOutOfBoundsException: 910
at java.util.ArrayList.add(Unknown Source)
at Principal.run(Principal.java:73)
Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: 118
at java.util.ArrayList.add(Unknown Source)
at Principal.run(Principal.java:73)
Y vemos los problemas de concurrencia....
¡GENIAL!
La única diferencia entre ArrayList y Vector es que algunos métodos no son synchronized, pero eso no hace que Vector sea thread safe. Echa un vistazo a CopyOnWriteArrayList para eso.
Gracias icoloma, miraremos lo que comentas.
Un saludo,