How can I create a concurrent List instance, where I can access elements by index? Does the JDK have any classes or factory methods I can use?
-
30Why not constructive? Several proposed CopyOnWriteArrayList that is not found in .Net. You can say that both questions relate to each other but not to close this one!!! – AlikElzin-kilaka Aug 03 '11 at 07:11
-
In .NET the equivalent of CopyOnWriteArrayList are the Immutable Collections. A concurrent collection is one that doesn't require locking to modify (like ConcurrentQueue etc), NOT one that copies its contents each time it's copied. – Panagiotis Kanavos Nov 21 '13 at 16:04
-
1I have no idea why Jarrod Roberson would think it was a good idea to take the detailed edits made by Stephan and revert them back to the original, poorly-phrased question. Jarrod's answer is still a perfectly acceptable one. In fact, CopyOnWriteArrayList is the only concurrent class implementing List in the JDK. Puzzled... – Matt Passell Jul 20 '15 at 14:08
-
13Because the accepted answer was to the **original question** and Stephan put a completely unrelated question with a bunch of source code that the **original** poster did not include **anywhere** changing the question completely, which generated more answers that were suggesting things other than the `List` which the original specifically says is a **requirement** which is considered vandalism. A moderator already locked the question because of the people that are complaining that the answers do not answer that vandalized version of the question. – Jul 20 '15 at 15:13
-
1/`locked`/`closed`/ previous comment – Jul 20 '15 at 15:49
-
11There's no reason for this question to be closed. It asks about classes in the JDK, which is nothing like searching for a library; it's the base of Java. – maaartinus Sep 02 '18 at 17:10
7 Answers
ConcurrentLinkedQueue
If you don't care about having index-based access and just want the insertion-order-preserving characteristics of a List, you could consider a java.util.concurrent.ConcurrentLinkedQueue
. Since it implements Iterable, once you've finished adding all the items, you can loop over the contents using the enhanced for syntax:
Queue<String> globalQueue = new ConcurrentLinkedQueue<String>();
//Multiple threads can safely call globalQueue.add()...
for (String href : globalQueue) {
//do something with href
}

- 303,325
- 100
- 852
- 1,154

- 4,549
- 3
- 24
- 39
-
4I think that the simplified for statement (`:`) is called foreach: http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html – AlikElzin-kilaka Sep 03 '14 at 06:16
-
2@AlikElzin-kilaka You're right. I think that name has always bothered me, because the actual syntax doesn't include the word "each", but I'll update the answer to use the official name. :) – Matt Passell Sep 03 '14 at 13:05
-
4@AlikElzin-kilaka Nitpicking, but according to the [JLS version 8](https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2) it is called the "enhanced for statement". The same in the [java tutorial](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html). – Roland May 24 '17 at 06:38
-
1@Roland definitely NOT nitpicking. There is (now) a difference between "for each" and "enhanced for" in Java. – hfontanez Nov 27 '18 at 21:37
-
@hfontanez Are you referring to [Stream.forEach](https://docs.oracle.com/javase/10/docs/api/java/util/stream/Stream.html#forEach(java.util.function.Consumer))? – Roland Nov 28 '18 at 06:45
-
4@Roland indirectly. I believe they renamed the "for each loop" to "enhanced for" to eliminate confusion between the Stream.forEach and what is now known as the enhanced for. – hfontanez Dec 04 '18 at 17:24
-
1
There is a concurrent list implementation in java.util.concurrent. CopyOnWriteArrayList in particular.

- 303,325
- 100
- 852
- 1,154
-
106Note it copies the whole list on every insert, so it is often inefficient. – dfrankow Mar 28 '13 at 12:56
-
27@dfrankow But it can more *more* efficient if you're iterating much more than you're updating. – arkon Jul 18 '15 at 18:13
-
Doesn't work well as shown here. I have exceptions even though I just use its addAll method and read it using stream. https://stackoverflow.com/questions/1527519/copyonwritearraylist-throwing-currentmodificationexception – devssh Mar 26 '18 at 10:01
-
1This answer – accepted and with 200+ upvotes – is misleading as being the right way to solve concurrency with an ArrayList. As the earlier comments describe, CopyOnWriteArrayList is _not_ a good fit if the usage is mostly writes, with few reads. The answer posted by @Oliv is more complete and informative. – Kaan Jul 13 '22 at 19:52
Disclaimer : This answer was published in 2011, before JDK 5, and before much advanced and optimal concurrent APIs. So, while the following will work, it is not the best option.
You can very well use Collections.synchronizedList(List) if all you need is simple invocation synchronization:
List<Object> objList = Collections.synchronizedList(new ArrayList<Object>());

- 51,409
- 25
- 133
- 214
-
87The result of `synchronizedList` is "synchronized" but not "concurrent". One fundamental issue that many List operations -- which are index-based -- are themselves not atomic and need to be part of a larger mutual exclusion construct. – Aug 02 '11 at 18:02
-
6IMO, asing a `Vector` is more straightforward rather than `Collections.synchronizedList(new ArrayList – Stephan Nov 21 '13 at 16:05
Because the act of acquiring the position and getting the element from the given position naturally requires some locking (you can't have the list have structural changes between those two operations).
The very idea of a concurrent collection is that each operation on its own is atomic and can be done without explicit locking/synchronization.
Therefore getting the element at position n
from a given List
as an atomic operation doesn't make too much sense in a situation where concurrent access is anticipated.

- 302,674
- 57
- 556
- 614
-
8Joachim, I think you hit the nail on the head. Take for example, a read-only list as a concurrent list. Getting the element at position N from the list not only makes sense, but it is the nutshell of the problem. So, an immutable list (lower case L) would be a good example, but it is not a List (upper case L). The CopyOnWriteArrayList is concurrent, but many people don't like the performance. A solution along the lines of ropes (string ropes) would probably be a good winner. – johnstosh Oct 08 '13 at 12:12
-
2Very good point. But the List the OP is going use might have very specific usage. E.g. it might be filled in concurrent environment, then "locked" (whatever it means) and then accessed safely by index. So, in the first phase of filling such a List will still require a thread-safe implementation. Unfortunately, the OP was not specific about how the List he is looking for is going to be used. – igor.zh Feb 05 '18 at 21:51
You have these options:
Collections.synchronizedList()
: you can wrap anyList
implementation (ArrayList
,LinkedList
or a 3rd-party list). Access to every method (reading and writing) will be protected usingsynchronized
. When usingiterator()
or enhanced for loop, you must manually synchronize the whole iteration. While iterating, other threads are fully blocked even from reading. You can also synchronize separately for eachhasNext
andnext
calls, but thenConcurrentModificationException
is possible.CopyOnWriteArrayList
: it's expensive to modify, but wait-free to read. Iterators never throwConcurrentModificationException
, they return a snapshot of the list at the moment of iterator creation even if the list is modified by another thread while iterating. Useful for infrequently updated lists. Bulk operations likeaddAll
are preferred for updates - the internal array is copied less many times.Vector
: very much likesynchronizedList(new ArrayList<>())
, but iteration is synchronized too. However, iterators can throwConcurrentModificationException
if the vector is modified by another thread while iterating.
Other options:
Queue
orDeque
might be an alternative if you only add/remove at the ends of the list or iterate it.Queue
allows only adding at one end and removing from the other end,Deque
allows adding and removing on both ends. There's no access by index. There are multiple implementations with better concurrency properties than anyList
can provide. Look at "All Known Implementing Classes" in the Queue javadoc, those implementations that are in thejava.util.concurrent
package are concurrent. You can also have a look at JCTools, it contains faster queue implementations specialized for single consumer or single producer.Collections.unmodifiableList()
: wait-free, thread-safe, but non-modifiableList.of
&List.copyOf
: Another non-modifiable list in Java 9 and later.

- 10,221
- 3
- 55
- 76
CopyOnWriteArrayList is a thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.
CopyOnWriteArrayList is a concurrent alternative of synchronized List implements List interface and its part of java.util.concurrent packageand its a thread-safe collection.
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
CopyOnWriteArrayList is fail-safe and doesn't throw ConcurrentModificationException when underlying CopyOnWriteArrayList is modified during Iteration use a separate copy of ArrayList.
This is ordinarily too costly because copy array involved every update operation a cloned copy will be created. CopyOnWriteArrayList is the best choice only for frequent read operation.
/**
* Returns a shallow copy of this list. (The elements themselves
* are not copied.)
*
* @return a clone of this list
*/
public Object clone() {
try {
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> clone =
(CopyOnWriteArrayList<E>) super.clone();
clone.resetLock();
return clone;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}

- 10,864
- 5
- 72
- 96
Mostly if you need a concurrent list it is inside a model object (as you should not use abstract data types like a list to represent a node in a application model graph) or it is part of a particular service, you can synchronize the access yourself.
class MyClass {
List<MyType> myConcurrentList = new ArrayList<>();
void myMethod() {
synchronzied(myConcurrentList) {
doSomethingWithList;
}
}
}
Often this is enough to get you going. If you need to iterate, iterate over a copy of the list not the list itself and only synchronize the part where you copy the list not while you are iterating over it.
Also when concurrently working on a list you usually do something more than just adding or removing or copying, meaning that the operation becomes meaningful enough to warrent its own method and the list becomes member of a special class representing just this particular list with thread safe behavior.
Even if I agree that a concurrent list implementation is needed and Vector / Collections.sychronizeList(list) do not do the trick as for sure you need something like compareAndAdd or compareAndRemove or get(..., ifAbsentDo), even if you have a ConcurrentList implementation developers often introduce bugs by not considering what is the true transaction when working with a concurrent lists (and maps).
These scenarios where the transactions are too small for what the intended purpose of the interaction with a concurrent ADT (abstract data type) always lead to me hide the list in a special class and synchronizing access to this class objects method using the synchronized on the method level. Its the only way to be sure that the transactions are correct.
I have seen too many bugs to do it any other way - at least if the code is important and handles something like money or security or guarantees some quality of service measures (e.g sending message at least once and only once).

- 5,127
- 8
- 46
- 77
-
3Synchronized locks so only 1 thread can access. Concurrent means multiple thread access with minimum locks. – AlikElzin-kilaka Oct 06 '20 at 10:00
-
First minimum locks is an arbitrary notion. Within a synchronized block the thread has exclusive access to a certain resource. But observing multiple processes from the outside would yield in the conclusion that multiple threads/'processes' could access the same resource (concurrent list) 'simultaneously' but in a thread safe fashion. e.g. One thread adds 100 elements one by one while another thread access the same list and copies it when the list contains 50 elements. That is called simultaneous or concurrent access of the resource as both threads access the same resource. – Martin Kersten Oct 10 '20 at 22:13
-
To let other threads wait while a not thread safe resource is accessed is a fully valid approach to implement concurrency. I do not think this answer should be voted down. Especially with lists in many cases I would prefer to access a very fast ArrayList with locking when I do not have to access a very large list very often than to CopyOnWrite for example which can be very costly. – Code ninetyninepointnine Dec 03 '21 at 20:03