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?