你的总体结构是不是线程安全的
发起的全过程检查myMap
和潜在另一个线程开始执行的线程。
if (myMap != null) {
doSomethingInAnotherThread();
}
// something can set `myMap` to null here...
被调度运行的代码将在某个时候做
void inAnotherThread() {
myMap.access();
}
,但没有更多的保证myMap
仍然是因为它以前一样。如果有可以改变什么myMap
指线程然后做
void inAnotherThread() {
if (myMap != null) {
myMap.acess();
}
}
因为你访问myMap
两次仍不能线程安全的,每次也可以是不同的。例如。一旦你访问它,它在if
但是null
之内不是null。一种解决方案是复制引用,以便在使用引用时不会更改该引用的本地副本。
void inAnotherThread() {
Map localReference = myMap;
if (localReference != null) {
localReference.acess();
}
}
是否是线程安全取决于myMap
。一个是否是volatile
(或final
)或不是。如果是:其他线程保证可以看到myMap
引用的最新版本,如果没有的话:没有保证。 (注:我觉得runOnUiThread
建立了之前发生关系,因为它在内部进行同步,因此,你应该有某种形式的保证,看看最近的参考版本)
下一个点,一旦你有给一个参考正确的Map
实例就是你可以安全地使用它。简单的HashMap
不是线程安全使用。如果你打电话.get()
它仍然可以炸毁你如果 - 在同一时间 - 另一个线程调用put
/remove
/..也因此变化数据,同时.get
访问它。
你可以将它包装在Collections.synchronizedMap(map)
这将使单个操作像get
原子,以便其他线程不能干涉。但它仍然不是线程安全的。例如。如果不进行外部同步,则遍历这些值仍然会失败。这个问题可以通过使用支持迭代的ConcurrentHashMap
来解决。
Threadsafety取决于很多因素,并在你的什么的线程安全是定义。什么是你写的已经线程,如果你能保证,一旦它被设置为!= null
myMap
是永远不会改变,你知道后台线程完成修改myMap
因此它是安全的UiThread访问它。
在初始化myMap Map之后运行这段代码,所以它不会为空。 –
你打电话给谁?如果它是从UiThread中调用的,它将直接内联执行,就好像没有'Runnable'一样。 – zapl
我忘了提及代码没有从UI线程运行。要编辑它。 – npace