Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java ArrayList - Are add() calls from one thread always readable from another?

Thread 1: Call list.add()
Thread 1: Exits list.add()
Thread 2: Call list.get(list.size()-1)

I have a scenario where I can guarantee that Thread 1 will complete the add() call before Thread 2 make the get() call. Will Thread 2 always see the changes made by Thread 1 in this case? Or would the internal ArrayList variables need to be marked as volatile?

Edit: For those who are curious about why I can guarantee it. I have a sequence of events from a server that look like this:

Event A1
Event A2
Event A3
Event B

The events are dispatched sequentially by a single thread. I want to capture a list of all the A events so my code looks like this:

List<EventA> eventAList = new ArrayList<>();
connection.addListenerForEventAs(eventAList::add);

connection.waitForEventB();

//Here I am doing operations on the eventAList
like image 788
bcoughlan Avatar asked Apr 16 '15 10:04

bcoughlan


1 Answers

First of all, you will have to ensure that a happens before relationship exists between call of add() by thread-1 and call to get() by thread-2. Completion of call and happens before are totally different.

Unless you do that, your code will not be thread-safe. Why?. Thread-1 might finish the call to add() before thread-2 calls get(). But what is the guarantee that Thread-2 will not make a local copy of the list (keep it handy)?. add() method doesn't ensure a happens-before. So, there is no guarantee that the value added by the first thread is even written completely and is visible to thread-2 .

Use CopyOnWriteArrayList or Collections.SynchronizedList() in Multi-threaded environment.

like image 69
TheLostMind Avatar answered Nov 18 '22 16:11

TheLostMind