Your general structure is not thread-safe
The thread that initiates the whole process checks myMap
and initiates execution in potentially another thread.
if (myMap != null) {
doSomethingInAnotherThread();
}
// something can set `myMap` to null here...
The code that is scheduled to run will at some point do
void inAnotherThread() {
myMap.access();
}
but there is no more guarantee that myMap
is still the same as it was before. If there are threads that can change what myMap
refers to then doing
void inAnotherThread() {
if (myMap != null) {
myMap.acess();
}
}
would still not be thread safe since you access myMap
twice and it can be different each time. E.g. It is not null inside the if
but null
once you access it. One solution is to copy the reference so nothing can change your local copy of that reference while you work with it.
void inAnotherThread() {
Map localReference = myMap;
if (localReference != null) {
localReference.acess();
}
}
Whether that is threadsafe or not depends on myMap
. For one whether it is volatile
(or final
) or not. If it is: other threads are guaranteed to see the most recent version of what myMap
refers to, if not: nothing guaranteed. (Note: I think runOnUiThread
established a happens-before relation since it synchronizes internally and you should therefore have some sort of guarantee to see a recent version of the reference)
The next point once you have a reference to the correct Map
instance is what you can do with it safely. A simple HashMap
is not threadsafe to use. If you call .get()
it could still blow up on you if - at the same time - another thread calls put
/remove
/.. and therefore changes data while .get
is accessing it.
You could wrap it in Collections.synchronizedMap(map)
which would make single operations like get
atomic so other threads can't interfere. But it's still not threadsafe for everything. E.g. iterating over the values will still fail if you don't synchronize externally. That problem could be solved by using a ConcurrentHashMap
which supports iteration as well.
Threadsafety depend on a lot of factors and on your definition of what thread safe is. What you wrote is already threadsafe if you can guarantee that myMap
is never changed once it is set to != null
and you know that the background thread is done modifying myMap
so it is safe for the UiThread to access it.