gpt4 book ai didi

android - Android中两个HandlerThreads之间的同步对象

转载 作者:行者123 更新时间:2023-11-29 01:27:36 26 4
gpt4 key购买 nike

我想在两个处理程序线程对象之间同步 Android 中的对象模型。一个对象是“可观察的”,第二个是观察者。它们都无限地在自己的线程中工作。观察者通过“registerListener”方法注册到 observable 并传递自己的引用和自己的处理程序。

并且可观察对象通过他们的回调方法(通过处理程序)传递给他们的观察者对象模型。对象模型被声明为“final”,因为我没有创建无限新对象,而是用新值(getter 和 setter)更新它的字段。

我不想将对象引用传递给观察者(对象是可变的)并且我不想使用“同步”关键字,因为我不想阻塞线程。

所以我的想法是在“可观察”对象中创建两个相同的对象模型。它们都是“最终的”,其中一个将由“可观察”对象使用并在其线程中更改,第二个将根据观察者线程中的第一个对象进行更改。因此,对象将由观察者处理程序同步。这是个好主意吗?我希望我的描述是清楚的。

最佳答案

一般来说,当你说“多线程”时,你是在暗示“同步”,因此你不使用 synchronized 关键字的愿望对我来说听起来很奇怪。现在回答你的问题......

如果我没理解错的话,您想在不同线程之间共享一些状态(存储在“对象模型”中),但不使用 synchronized 关键字。此外,您提到的 我不想将对象引用传递给观察者(对象是可变的) 暗示观察者不应该能够修改对象的状态。

如果上面的描述是正确的,那么你可以在“可观察线程”中复制你的“对象模型”,并将它传递给“观察线程”中的回调。这些方面的东西(未经测试):

private void notifyListeners() {
for (int i=0; i<mListeners.size(); i++) {
final ObjectModel copyModel = new ObjectModel(mModel); // Assuming copy-constructor exists
mHandlers.get(i).post(new Runnable{
mListeners.get(i).notify(copyModel);
});
}
}

请注意,这种方法有一些缺点:

  1. 复制构造后,传递给您的监听器的对象将不再“跟踪”可观察对象的状态。这意味着您的听众可能正在处理过时的数据。
  2. 您在每次调用 notifyListeners 方法时为每个监听器复制“对象模型”。这可能会成为一个主要的开销(取决于模型的大小、听众的数量和通知的速度)
  3. 如果您希望您的听众将来能够修改模型,则需要完全更改您的代码。

由于上述原因,除了最简单的情况外,我建议不要使用上述方法。在其他情况下,我会将原始对象传递给监听器并确保线程安全。一些可以帮助你的笔记:

  1. 为了防止听众修改模型,你可以使用Interface Segregation Principle .总体思路:定义两个单独的接口(interface) - 一个用于读取模型的状态,另一个用于更改此状态(例如 WritableModelReadableModel)。让您的“对象模型”同时实现这两者,然后将此模型作为 ReadableModel 传递给监听器。这样,您将只向监听器公开您模型的非可变 API。
  2. 由于只有一个线程可以改变模型的状态,您可以使用 volatile 成员而不是完全同步方案。这将减少对 synchronized block 的需求。请记住,虽然 volatile 关键字解决了可见性问题,但它没有解决原子性问题(即您仍然需要为模型的成员使用 synchronized以原子方式编写)。
  3. 您可以使用 java.util.concurrent.atomic 包中的类,而不是自己同步非原子编写的成员。

关于android - Android中两个HandlerThreads之间的同步对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067880/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com