gpt4 book ai didi

java - Android中的观察者模式与数据同步

转载 作者:行者123 更新时间:2023-11-30 01:18:11 32 4
gpt4 key购买 nike

我想在Android中实现观察者模式。 observable 和观察者必须在它们自己的线程中工作 (HandlerThread)。可观察对象产生一些结果并每毫秒通知它们的观察者。观察者通过将自己和 Handler 引用作为参数进行注册。

示例代码:

public class Observable {

public interface Observer {
void notify(List<Object> results);
}

private HandlerThread handlerThread;
private List<Object> results = new ArrayList<>();
private final Map<Observer, ObserverWrapper> observers = new HashMap<>();

private void working() {
//Critial section...

//modifying results list...

synchronized (observers) {
for (ObserverWrapper wrapper : observers.values()) {
wrapper.notify(results);
}
}
}

public void register(Observer observer, Handler handler) {
synchronized (observers) {
//Create observer wrapper and add to map here...
}
}

public void unregister(Observer observer) {
synchronized (observers) {
//Remove observer from the map...
}
}

private static final class ObserverWrapper {
private final Observer observer;
private final Handler handler;

public ObserverWrapper(Observer observer, Handler handler) {
this.observer = observer;
this.handler = handler;
}

public void notify(final List<Object> results) {
//The observable thread

handler.post(new Runnable() {
void run() {
//The observer thread
//Critical section...
observer.notify(results);
}
});
}
}
}

问题是:如何同步传递给所有观察者的结果列表?我不能为每个观察者使用一个副本,因为它会导致高内存使用率。

最佳答案

我可以想到三种选择:

  1. 使用结果对象作为监视器。这需要最少的更改,但这 a) 不是很干净,因为对象本身并没有说明作为监视器的任何内容。 b) 由于更新每隔几毫秒进行一次,因此担心观察者线程会长时间锁定生产者线程。生产者和观察者都必须:

    同步(结果){

    //...

  2. 将显式锁定对象传递给 notify() 并显式使用它:

private final Object lock = new Object();

同步(锁定){ //更新结果

...同步(锁定){ //读取结果

  1. 您提到您不想通过复制结果来减少 GC 占用空间,但这可能是并发性最高的选项。如果我正在写它,我会这样做。其实还有一个更好的选择,内存方面更乐观的选择,就是CopyOnWriteArrayList,只有同时读写才会复制:

https://developer.android.com/reference/java/util/concurrent/CopyOnWriteArrayList.html

关于java - Android中的观察者模式与数据同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37527594/

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