![](/img/trans.png)
[英]How can I synchronize two threads in Java by extending the Thread class?
[英]How can I synchronize the class so that I can use from UI thread and background threads?
我有一个实用程序类如下:
public class MetaUtility {
private static final SparseArray<MetaInfo> metaInfo = new SparseArray<>();
public static void flush() {
metaInfo.clear();
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
metaInfo.append(key, info);
}
public static MetaInfo getMeta(int key) {
return metaInfo.get(key);
}
}
这个类很简单,我希望有一个“中心”容器可以跨类/活动使用。
问题是线程化。
现在它被填充(即调用addMeta
)只在代码中的一个位置(不在UI线程中)并且不会改变。
getter由UI线程访问,在某些情况下由后台线程访问。
仔细检查代码我不认为我最终会遇到后台线程会向稀疏数组添加元素而其他线程会尝试访问它的情况。
但是除非他非常了解代码,否则这对于有人知道是非常棘手的。
我的问题是,我如何设计我的类,以便我可以安全地从包括UI线程在内的所有线程中使用它?
我不能只是添加一个synchronized或make it阻止,因为这会阻止UI线程。 我能做什么?
你应该只对你的对象进行同步,因为你的类现在只是一个围绕SparseArray的包装类。 如果存在线程级别阻塞问题,那么它们可能是因为在项目的其他部分中滥用此对象(我认为类只考虑它只公开公共静态方法)。
第一次拍摄可以synchronized
。
@Jim线程调度延迟怎么样?
Android调度程序基于Linux,它被称为完全公平的调度程序(CFS)。 它是“公平的”,因为它试图平衡任务的执行,不仅基于线程的优先级,而且还通过跟踪给予线程的执行时间量。
如果您看到“跳过的xx帧!应用程序可能在其主线程上做了太多工作”,那么需要进行一些优化。
如果你有无竞争锁定,你不应该害怕使用synchronized
。 在这种情况下,锁应该thin
,这意味着它不会将阻塞的线程传递给OS
调度程序,但会尝试再次获取锁之后的几条指令。 但是如果您仍然想要编写非阻塞实现,那么您可以使用AtomicReference
来保存SparseArray<MetaInfo>
数组并使用CAS
更新它。
代码可能像这样:
static AtomicReference<SparseArray<MetaInfo>> atomicReference = new AtomicReference<>();
public static void flush() {
atomicReference.set(new SparseArray<MetaInfo>);
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
do {
SparseArray<MetaInfo> current = atomicReference.get();
SparseArray<MetaInfo> newArray = new SparseArray<MetaInfo>(current);
// plus add a new info
} while (!atomicReference.compareAndSet(current, newArray));
}
public static MetaInfo getMeta(int key) {
return atomicReference.get().get(key);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.