wild84
2018-05-18 00:33
采纳率: 91.6%
浏览 1.8k
已采纳

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

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

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

8条回答 默认 最新

  • threenewbee 2018-05-18 01:41
    已采纳

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

    打赏 评论
  • 水里的魚儿 2018-05-18 01:38

    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);
    }
    
    打赏 评论
  • jxiaolu 2018-05-18 02:10
    打赏 评论
  • qq_36238292 2018-05-18 02:12

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

    打赏 评论
  • ZhihengTao 2018-05-18 02:20

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

    建议

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

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

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

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

    多线程

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

    关键

    1. 问题存在与否
    2. 问题存在时,瓶颈在哪里
    打赏 评论
  • qq_41399931 2018-05-18 02:27

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

    打赏 评论
  • Royal_lr 2018-05-18 02:28

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

    打赏 评论
  • limeigui 2018-05-20 02:16

    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();
                }
            }
     }
    
    打赏 评论

相关推荐 更多相似问题