I've read Oracle's documentation, which states (among a few other things) that:
Reads and writes are atomic for reference variables
So that means, assuming I understand this correctly, that the below code is thread safe without needing volatile
, synchronized
, or using a Lock
class, since the actual assignment of otherHashlist
to hashlist
is atomic and the assignment from hashlist
to tempHashlist
is also atomic.
public class SomeClass
{
private HashMap<Integer, ArrayList<MyObject>> hashlist = null;
// ...Thread/Runnable logic to periodically call set()...
private void set()
{
HashMap<Integer, ArrayList<MyObject>> otherHashlist = new HashMap<Integer, ArrayList<MyObject>>();
// ...populate otherHashlist...
hashlist = otherHashlist;
}
public ArrayList<MyObject> get(int i)
{
HashMap<Integer, ArrayList<MyObject>> tempHashlist = hashlist;
return new ArrayList<MyObject>(tempHashlist.get(i));
}
}
Additionally, hashlist
is never accessed in any way outside of get()
and set()
. set()
is also not able to be called, directly or indirectly, by anything outside of the class. The ArrayList returned by get()
is new
, so operations that modify the ArrayList (set(), remove(), etc) will not affect the original ArrayList in hashlist
. I also have not defined any setter methods on MyObject
, all of whose member variables are either private final int
, private final long
, or private final String
.
So, my question then, is: Is this code actually thread safe? Or is there some assumption I'm making/angle I'm missing that would make this unsafe?