Mi è venuto in mente il seguente codice per simulare un po 'uno scenario reale.
100 attività vengono eseguite in parallelo e aggiornano lo stato completato al programma principale. Io uso un CountDownLatch per attendere il completamento dell'attività.
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();
}
}
}
Quando ho eseguito l'applicazione di 10 volte e almeno 3 o 4 volte il programma non è stato stampato un numero corretto di attività completate. Idealmente dovrebbe stampare 100 (se non si verificano eccezioni). Ma in alcuni casi stava stampando 98, 99 ecc.
Così dimostra che gli aggiornamenti simultanei di ArrayList non daranno risultati corretti.
Se si sostituisce ArrayList con una versione sincronizzata, il programma restituisce i risultati corretti.
fonte
2015-01-18 05:20:13
"è stata la mia esperienza che entrambi gli oggetti sono stati aggiunti bene" voglio solo sottolineare che questa è solo pura fortuna. Probabilmente la finestra per un problema di corruzione dei dati con ArrayList è estremamente piccola, ma esiste ancora –
Giusto, ed è una specie del mio punto. Nella stragrande maggioranza dei casi non ci saranno problemi; ma non programmiamo per la maggior parte dei casi. Per questo motivo ho fortemente raccomandato di non usare ArrayList. – derivation