java多线程观察者模式如何实现?

假设有一个对象subject和500个观察者;
当对象有更新信息时通知500个观察者,
因担心循环通知耗时过久,考虑在通知时使用多个
线程进行通知。
以上功能应该如何实现?

8个回答

观察者模式本身没有必要多线程。
你需要将通知和对象的处理分离,可以每个对象拥有一个消息队列,发送通知的时候添加消息到对象的消息列表中。
500个对象乃至·10000个对象都可以很快发送。而每个对象自己读取消息列表后处理,这个放在多线程中完成。这么做的好处是,每个对象的消息列表是单独同步的,因此没有需要全局加锁的对象,才能发挥多线程的最大的优势。

wild84
wild84 你这个设计到消息队列的使用了
大约 2 年之前 回复

Observable notifyObservers( )方法获取是否改变,改变的话,依次通知所有观察者(即循环调用所有观察的update()方法);
1、在Observer的 update()实现线程;
public void update(){
Runnable mRunnable = new Runnable(
public void run() {
/**Task**/
}
);

Thread mThread = new Thread(mTestRunnable);
mThread.start();
}

2、覆写Observable notifyObservers( )方法;
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal;

    synchronized (this) {
        /* We don't want the Observer doing callbacks into
         * arbitrary code while holding its own Monitor.
         * The code where we extract each Observable from
         * the Vector and store the state of the Observer
         * needs synchronization, but notifying observers
         * does not (should not).  The worst result of any
         * potential race-condition here is that:
         * 1) a newly-added Observer will miss a
         *   notification in progress
         * 2) a recently unregistered Observer will be
         *   wrongly notified when it doesn't care
         */
        if (!changed)
            return;
        arrLocal = obs.toArray();
        clearChanged();
    }

    for (int i = arrLocal.length-1; i>=0; i--)//在这里调用线程,然后在线程再调用观察者的update()方法;
        ((Observer)arrLocal[i]).update(this, arg);
}

比如5个线程,把500个观察者分成5段,每个线程发送100通知。

首先 "循环通知耗时过久" 这个问题是否存在都是未知, 需要先确定问题存在,再讨论如何解决问题才有意义

建议

先测定循环耗时,确定问题存在与否

  • 循环前后计时
  • 循环内只做**同步的**消息通知操作,不做**同步的**消息处理操作

如果问题不存在,皆大欢喜,不用管了.

如果问题存在,那就需要确定其瓶颈所在, 假定瓶颈在循环体内某个操作,可以考虑循环体内操作在多线程下进行.

多线程

但是多线程可能会带来其他开销,如线程创建,线程销毁,消息同步等. 一般M任务N线程**(M >> N)**问题,可以考虑**线程池**模型.
假定问题存在的情况下, 最终是否采用多线程,也还是要根据性能瓶颈,比较采用前后开销大小来决定.

关键

  1. 问题存在与否
  2. 问题存在时,瓶颈在哪里

你就是想用多线程 做通知而已,直接
int threadNum=30;
ExecutorService pool=Executors.newFixedThreadPool(threadNum);
pool.execute(new Runnable() {
@Override
public void run() {
执行通知
}
});
线程池做通知就行了

把500个观察者分成5段,每个线程发送100通知

1、首先观察者模式本身,不区分是否多线程。

2、观察者模式: 就是订阅分发机制,通过实现注册哪些接口实现类所关注的动作。然后再出发时,分别回调就可以。原理示意代码:

interface IMyAction
{
DoAction();
}

class ObserManager
{
private List list = new List;

        public bool Subsribe(IMyAction action)
        {
            list.Add(action);
        }

        public bool DoAction()
        {
            foreach(IMyAction action in  list)
            {
                action.DoAction();
            }
        }
 }
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐