假设有一个对象subject和500个观察者;
当对象有更新信息时通知500个观察者,
因担心循环通知耗时过久,考虑在通知时使用多个
线程进行通知。
以上功能应该如何实现?
观察者模式本身没有必要多线程。
你需要将通知和对象的处理分离,可以每个对象拥有一个消息队列,发送通知的时候添加消息到对象的消息列表中。
500个对象乃至·10000个对象都可以很快发送。而每个对象自己读取消息列表后处理,这个放在多线程中完成。这么做的好处是,每个对象的消息列表是单独同步的,因此没有需要全局加锁的对象,才能发挥多线程的最大的优势。
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();
}
}
}
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);
}
可以参考:
https://blog.csdn.net/mastershaw/article/details/71271862?utm_source=itdadao&utm_medium=referral
比如5个线程,把500个观察者分成5段,每个线程发送100通知。
首先 "循环通知耗时过久" 这个问题是否存在都是未知, 需要先确定问题存在,再讨论如何解决问题才有意义
先测定循环耗时,确定问题存在与否
如果问题不存在,皆大欢喜,不用管了.
如果问题存在,那就需要确定其瓶颈所在, 假定瓶颈在循环体内某个操作,可以考虑循环体内操作在多线程下进行.
但是多线程可能会带来其他开销,如线程创建,线程销毁,消息同步等. 一般M任务N线程**(M >> N)**问题,可以考虑**线程池**模型.
假定问题存在的情况下, 最终是否采用多线程,也还是要根据性能瓶颈,比较采用前后开销大小来决定.
把500个观察者分成5段,每个线程发送100通知
你就是想用多线程 做通知而已,直接
int threadNum=30;
ExecutorService pool=Executors.newFixedThreadPool(threadNum);
pool.execute(new Runnable() {
@Override
public void run() {
执行通知
}
});
线程池做通知就行了