Before going into the answer, let's first check if I understand the situation and the question.
- Assumption as stated in problem description:
Only a single thread creates new versions of the list, based on the previous value of publicDataObject
, and stores that new list in publicDataObject
.
- Derived assumption:
Other threads access DataObject
elements from that list, but do not add, remove or change the order of elements.
- If this assumption holds, the answer is below.
- Otherwise, please make sure your question includes this in its description. This makes the answer much more complex, though, and I advise you to study the topic of concurrency more, for example by reading a book about Java concurrency.
- Additional assumption:
The DataObject
objects themselves are thread-safe.
- If this assumption does not hold, this would make the scope of the question too broad and I would suggest to study the topic of concurrency more, for example by reading a book about Java concurrency.
Answer
Given that the above assumptions are true, you do not need a lock, however, you cannot just access publicDataObject
from multiple threads, using its definition in you code example. The reason is the Java Memory Model. The Java Memory Model makes no guarantees whatsoever about threads seeing changes made by other threads, unless you use special language constructs like atomic variables, locks or synchronization.
Simplified, these constructs ensure that a read in one thread that happens after a write in another, can see that written value, as long as you are using the same construct: the same atomic variable, lock or synchronisation on the same object. Locks and intrinsic locks (used by synchronisation) can also ensure exclusive access of a single thread to a block of code.
Given, again, that the above assumptions are true, you can suffice using an AtomicReference, whose get
and set
methods have the desired relationship:
// Definition
public AtomicReference<List<DataObject>> publicDataObject;
The reasons that a simple construct can be used that "only" guarantees visibility are:
- The list that
publicDataObject
refers to, is always a new one (the first assumption). Therefore, other threads can never see a stale value of the list itself. Making sure that threads see the correct value of publicDataObject
is therefore enough
- As long as other threads don't change the list.
- If in addition, only thread sets
publicDataObject
, there can be no race conditions in setting it, for example loosing updates that are overwritten by more recent updates before ever being read.