Se me ocurrió el siguiente código para imitar un escenario del mundo real.
100 tareas se ejecutan en paralelo y actualizan su estado completo al programa principal. Uso CountDownLatch para esperar la finalización de la tarea.
import java.util.concurrent.*;
import java.util.*;
public class Runner {
// Should be replaced with Collections.synchronizedList(new ArrayList<Integer>())
public List<Integer> completed = new ArrayList<Integer>();
/**
* @param args
*/
public static void main(String[] args) {
Runner r = new Runner();
ExecutorService exe = Executors.newFixedThreadPool(30);
int tasks = 100;
CountDownLatch latch = new CountDownLatch(tasks);
for (int i = 0; i < tasks; i++) {
exe.submit(r.new Task(i, latch));
}
try {
latch.await();
System.out.println("Summary:");
System.out.println("Number of tasks completed: "
+ r.completed.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
exe.shutdown();
}
class Task implements Runnable {
private int id;
private CountDownLatch latch;
public Task(int id, CountDownLatch latch) {
this.id = id;
this.latch = latch;
}
public void run() {
Random r = new Random();
try {
Thread.sleep(r.nextInt(5000)); //Actual work of the task
} catch (InterruptedException e) {
e.printStackTrace();
}
completed.add(id);
latch.countDown();
}
}
}
cuando me encontré con la aplicación de 10 veces y al menos 3 a 4 veces el programa no se imprime un número correcto de las tareas completadas. Lo ideal sería imprimir 100 (si no se producen excepciones). Pero en algunos casos estaba imprimiendo 98, 99, etc.
Por lo tanto, prueba que las actualizaciones concurrentes de ArrayList no darán resultados correctos.
Si reemplazo el ArrayList con una versión Sincronizada, el programa genera los resultados correctos.
"Ha sido mi experiencia que ambos objetos se han agregado bien" solo quiero señalar que esto es pura suerte. Es probable que la ventana para un problema de corrupción de datos con ArrayList sea extremadamente pequeña, pero aún existe –
Correcto, y ese es mi punto. En la gran mayoría de los casos, no habrá problema; pero no programamos para la mayoría de los casos. Por lo tanto, recomiendo encarecidamente no usar ArrayList. – derivation