Un processore single core può ancora generare ConcurrentModificationException?

Nov 01 2020

Se spawn 2 thread su un PC single core, accede mai, ad esempio, a uno ArrayListnello stesso tempo, quindi verrà lanciato ConcurrentModificationException?

Il mio istinto mi dice che sebbene ci siano 2 thread, non possono raggiungere il vero parallelismo perché c'è un unico core e ciò che può fare principalmente è saltare da un thread all'altro ma senza eseguire un'istruzione come arrayList.add(element)nello stesso tempo.

Risposte

14 OleV.V. Nov 01 2020 at 18:20

TL; DR: Sì

    List<String> myList = new ArrayList<String>(Arrays.asList("My string"));
    Iterator<String> myIterator = myList.iterator();
    myList.add("Another string");
    myIterator.next();

Risultato:

Exception in thread "main" java.util.ConcurrentModificationException
  at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
  at com.ajax.YourClass.yourMethod(YourClass.java:134)

Non dovresti modificare la raccolta durante l'iterazione su di essa. In pratica il ConcurrentModificationExceptionsolito arriva (ma non è garantito) quando si richiama next()un iteratore dopo aver aggiunto o rimosso un elemento. E in pratica accade spesso quando aggiungi o rimuovi un elemento dall'interno di un ciclo che itera sulla raccolta, come ha detto Carciganicate nel commento.

O come ernest_k ha detto così bene nel commento:

"Concurrent" in ConcurrentModificationExceptionnon riguarda realmente il parallelismo

3 SolomonSlow Nov 01 2020 at 20:30

La concorrenza non è la stessa cosa del calcolo parallelo . Due attività (ad esempio, due thread) si verificano contemporaneamente se entrambe sono state avviate prima che una di esse sia terminata. Non hai bisogno di più CPU perché ciò avvenga.

Ma nota anche cosa ha detto @ernest_k in un commento: non è nemmeno necessario avere più di un thread affinché il tuo programma lanci un file ConcurrentModificationException. Tutto quello che devi fare è creare un iteratore per una raccolta, quindi modificare la raccolta e quindi provare a continuare a utilizzare l'iteratore dopo aver eseguito la modifica. Vale a dire, otterrai l'eccezione se modifichi la raccolta contemporaneamente a un'iterazione.