1,概念
1)java.util.Observable(
被观察者
)和java.util.Observer(观察者
),分别代表观察者模式中的Subject和Observer。
2)核心。 Observable/Subject中有包含一个观察者 Obsever的Vector列表
,当Subject被观察者发生changed
改变时,notifyObservers
通知所有observer观察者。
2,JDK观察者模式的支持
1)被观察者
public class Observable {
private boolean changed = false;//是否发生了改变
private Vector<Observer> obs;//(线程安全的)维护观察者列表
//添加、注册观察者。线程安全
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
}
//删除观察者
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
//通知所有的观察者
public void notifyObservers(Object arg) {
//snapshot
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();//Indicates that this object has no longer changed
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);//call observer的update方法
}
protected synchronized void setChanged() {
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
2)观察者Observer
public interface Observer {
//This method is called whenever the observed object is changed.
void update(Observable o, Object arg);
}
3,redis观察者模式(发布订阅功能)
1)pub、sub结构
image.png
publisher:通过 PUBLISH 命令向订阅者发送信息的客户端
subscriber:通过SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的客户端
channel:解耦发布者(publisher)和订阅者(subscriber)之间关系的中介
2)存储结构
订阅频道
struct redisServer {
// channlel - List<client>频道和订阅者client的列表
dict *pubsub_channels; // Map channels to list of subscribed clients
};
image.png
SUBSCRIBE
命令:将客户端添加到channel的订阅链表
中。
PSUBSCRIBE
命令:订阅channel或者pattern,将客户端和订阅的模式添加到redisServer.pubsub_patterns 当中。
redisServer.pubsub_channels是一个channel-list<client>的字典。
redisServer.pubsub_patterns是一个链表。
订阅模式
struct redisServer {
list *pubsub_patterns; // A list of pubsub_patterns
};
typedef struct pubsubPattern {
redisClient *client;
robj *pattern;
} pubsubPattern;
image.png
3)使用 PUBLISH 命令向订阅者发送消息。
1)在
redisServer.pubsub_channels 字典
中查找记录了订阅这个频道的所有客户端的链表,遍历这个链表
,将消息发布给所有订阅者。
2)遍历redisServer.pubsub_patterns 链表
,将链表中的模式和给定的频道进行匹配,如果匹配成功,那么将消息发布到相应模式的客户端当中。
3)publish pbkey "pbkey1"
subscribe pbkey
psubscribe pbkey
4)pubsub命令:redis2.8新增命令,客户端执行该命令,可以查看频道、模式的订阅信息。
pubsub channels [pattern]
pubsub numsub [channel-1]… :返回这些频道订阅者的数量。
pubsub numpat [pattern-1]… :返回这些频道订阅者的数量。
网友评论