在 Java 中实现观察者模式(Observer Pattern)时,有几个关键点需要特别注意,既能保证功能正确,也能避免常见的坑。下面从设计、线程安全、内存泄漏、性能几个方面来说明。
Java 本身提供了支持:
java.util.Observable(已废弃,不推荐)java.util.Observer(已废弃)推荐方式:
java.util.EventListenerjava.util.concurrent / RxJava / Spring 事件机制interface Observer {
void update(String message);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers(String msg) {
for (Observer o : observers) {
o.update(msg);
}
}
}
在通知观察者时,观察者列表可能被并发修改:
for (Observer o : new ArrayList<>(observers)) {
o.update(msg);
}
或使用 CopyOnWriteArrayList
如果:
需要保证:
✅ 推荐:
private final List<Observer> observers =
new CopyOnWriteArrayList<>();
❌ 不推荐:
synchronized (this) { ... } // 容易死锁或性能差
最常见问题:
✅ 解决方法:
removeObserver@Override
public void destroy() {
subject.removeObserver(this);
}
✅ 进阶:
WeakReference<Observer>(需谨慎)不要假设:
observerA 一定先于 observerB 执行
除非业务明确需要顺序(可使用队列)
观察者方法里:
executor.submit(() -> o.update(msg));
错误示例:
public void update() {
subject.removeObserver(this); // 可能 ConcurrentModificationException
}
✅ 解决:
通知时传参:
class Event {
private final String type;
private final Object data;
}
@EventListener
public void handle(UserCreatedEvent e) {}
eventBus.register(this);
eventBus.post(event);
适合复杂异步流
实现观察者模式要注意:
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。