How to Make My Arraylist Thread-Safe? Another Approach to Problem in Java

How do I make my ArrayList Thread-Safe? Another approach to problem in Java?

Use Collections.synchronizedList().

Ex:

Collections.synchronizedList(new ArrayList<YourClassNameHere>())

Concurrent threads adding to ArrayList at same time - what happens?

There is no guaranteed behavior for what happens when add is called concurrently by two threads on ArrayList. However, it has been my experience that both objects have been added fine. Most of the thread safety issues related to lists deal with iteration while adding/removing. Despite this, I strongly recommend against using vanilla ArrayList with multiple threads and concurrent access.

Vector used to be the standard for concurrent lists, but now the standard is to use the Collections synchronized list.

Also I highly recommend Java Concurrency in Practice by Goetz et al if you're going to be spending any time working with threads in Java. The book covers this issue in much better detail.

Java ArrayList.add() method thread safe for purely parallel adding?

No, it's not thread-safe. Wrap your list using Collections.synchronizedList(), or use explicit synchronization when accessing the list.

Why are we here, specifically, saying that ArrayList is not thread safe?

ArrayList is unsynchronized in implementation. When an object is unsynchronized it means that is is not locked while being modified structurally. A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.
What you are referring to is an array which the elements are being added to or being deleted from and can be modified this differs from it having its value being set.

Reference is in regards with the pointer of the start of the array but how many elements are there is in question and having an unsynchronized object being modified in the sense of elements while the elements are being iterated over by another thread the integrity of the elements in the list is hard to guarantee. I hope I was able to convey the message plainly.

Look for more details here in Oracle: Array List and ConcurrentModificationException

ArrayList:

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method.

ConcurrentModificationException:

Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification.

Thread-safe HashMap of Objects with Nested ArrayList

The thing you have to be clear about is what you mean by "thread safe".

I guess the question is adding Example objects to the HashMap thread safe?

Making the map synchronized guarantees that the structural modifications you make to the map are visible to all threads.

Also, is removing and adding AnotherObjet objects to the nested list thread-safe or should I declared it as synchronized ArrayList?

No: you would need to externally synchronize accesses to the lists if you want structural modifications to the lists to be visible in all threads.

That could mean using synchronizedList, but you could "manually" synchronize on the list, or even on the map (or one of a number of other ways that create happens-before guarantees).

How can I achieve the safe read/write concurrency on an ArrayList?

How can I achieve the safe read/write concurrency on an ArrayList?

It's hard to figure out what is actually happening to the list. Items are being added to the end of the while readers are consuming from the front but I can't tell if multiple readers read a single item or does every reader consume every element?

But regardless, I would consider switching to using a BlockingQueue like an ArrayBlockingQueue. ArrayList is not at all built for your use case. I would have a BlockingQueue for the work and then another BlockingQueue for the results. Again, this assumes that entries in your list are not consumed by multiple threads.

One of the main issues here is that synchronization performances two functions: mutex protection and memory synchronization. The writers have to lock so they don't collide but the readers need to lock to be able to see the writers' updates to the list.

In terms of the blocking specifics, some of your requirements are not possible because of the race conditions involved with dynamically extending the list.

I am making an assumption here that merely writing to the end of ArrayList is thread safe for the reader of the array's start

This is true unless the write to the end of the list causes the list to be reallocated. However, again, you need to synchronize on the list to see any of the updates made to the list by the writers. Even if your ArrayList is volatile the fields inside of the list are not.

I am making an assumption here that reallocating the memory of ArrayList is NOT thread safe for the reader of the array's start...

No it is not. No part of the ArrayList is thread safe when it comes to the array of data. I'd recommend looking at the source if there is any question. The following method is called from add(...) and any other method that changes the size of the list.

public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

Failed to make my ArrayList Thread-Safe. Exception in thread main java.lang.ClassCastException: What is wrong?

The issue that you're seeing is with this line:

tasks =   (ArrayList<Future<?>>) Collections.synchronizedList(new ArrayList<Future<?>>(cores));

Collections.synchronizedList doesn't return an ArrayList; it returns some subclass of List - java.util.Collections$SynchronizedRandomAccessList to be exact - and I don't know anything about that class other than it's a List, but it's not an ArrayList.

The easy solution to this is to declare tasks to be a List<Future<?>>:

List<Future<?>> tasks =
Collections.synchronizedList(new ArrayList<Future<?>>(cores));


Related Topics



Leave a reply



Submit