Android中的观察者模式和数据同步

时间:2016-05-30 14:00:54

标签: java android multithreading synchronization

我想在Android中实现观察者模式。观察者和观察者必须在他们自己的线程中工作(extension UIPinchGestureRecognizer { func scale(view: UIView) -> (x: CGFloat, y: CGFloat)? { if numberOfTouches() > 1 { let touch1 = self.locationOfTouch(0, inView: view) let touch2 = self.locationOfTouch(1, inView: view) let deltaX = abs(touch1.x - touch2.x) let deltaY = abs(touch1.y - touch2.y) let sum = deltaX + deltaY if sum > 0 { let scale = self.scale return (1.0 + (scale - 1.0) * (deltaX / sum), 1.0 + (scale - 1.0) * (deltaY / sum)) } } return nil } } )。可观察对象产生一些结果并通知观察者每毫秒。观察者通过传递自己和HandlerThread引用作为参数进行注册。

示例代码:

Handler

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

2 个答案:

答案 0 :(得分:1)

我可以想到三个选项:

  1. 将结果对象用作监视器。这需要最小的改变,但这a)不是很干净,因为对象本身并没有说明是一个监视器。 b)鉴于每隔几毫秒就会发生更新,因此担心观察者线程会长时间锁定生产者线程。制片人和观察者都必须:

    synchronized(results){

    // ...

    }

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

  3. private final Object lock = new Object();

    synchronized(lock){    //更新结果 }

    ... synchronized(lock){    //阅读结果 }

    1. 您提到您不想复制结果以减少GC占用空间,但这可能是最常用的选项。如果我写的话,我会这样做。实际上有更好的选择,在内存方面更乐观的选项,即CopyOnWriteArrayList,只有在同时读写时才会复制:
    2. https://developer.android.com/reference/java/util/concurrent/CopyOnWriteArrayList.html

答案 1 :(得分:0)

根据讨论,这是最常用的方法:

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

        //modifying results list...

        // Create a copy for observers to process
        List resultsToProcess = new ArrayList(results);

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