Java Observer与Observable源码解析

CodeBuddy 接入 MCP,一键生成网站! 2024 年 11 月,Anthropic 公司搞了个挺有意思的新玩意 - Model Context Protocol(模型上下文协议)简称为 MCP 协议。简单来说,它就是给 AI 和各类工具数据之间搭了个标准化的”桥梁”,让开发者不用再为对接问题头疼了。mcp.so如下图所示,这是 mcp.so 网站中的 MCP Server。使用百度/高德地图分析旅线计算时间接 Puppeteer 自动操作网页使用 Github/Gitlab 让大模型接管代码仓库。 阅读详情
前言

Observer与Observable是JDK中内置的类型,是实现观察者模式重要的两个类,学习设计模式的时候只是简单的知晓这两个类中的一些方法使用,并不知道具体是咋样的,所以特地研究了一下其源码实现,如果需要知道怎么使用,请移步 设计模式总结

Observer

先来看下源码

//此类位于util包中
 package java.util;

 public interface Observer {
 //参数o是被观察者的引用,arg是被观察者传来的信息
     void update(Observable o, Object arg);
 }

很简单的一个接口,仅提供一个update方法用于接收通知者的通知做出相应改变,其中第一个Observable类型的参数是被观察者的引用,当你需要与被观察者进行交互的时候,就需要这个引用了,另一个Object类型的参数是被观察者传递过来的信息,可以是实体,String,int,所以设置成了Object。

Observable

具有如下成员

public class Observable {
   //用来标志是否变化,默认无变化
    private boolean changed = false;
    //存储观察者对象
    private Vector<Observer> obs;
    //空构造方法
    public Observable(){};
    //设置变化,调用后changed为true
    protected synchronized void setChanged(){};
       //清除变化,调用后changed为false
    protected synchronized void clearChanged(){};
    //增加观察者,参数o为增加的对象
    public synchronized void addObserver(Observer o){};
    //删除观察者,参数o为被删除的对象
    public synchronized void deleteObserver(Observer o) {};
    //删除所有观察者
    public synchronized void deleteObservers(){};
    //是否变化
    public synchronized boolean hasChanged(){};
    //统计观察者数量然后返回
    public synchronized int countObservers(){};
    //通知所有观察者更新
    public void notifyObservers(){};
    //通知所有观察者更新,参数arg为通知内容
    public void notifyObservers(Object arg){};
}

源码如下

 package java.util;

  public class Observable {
      private boolean changed = false;  //是否改变状态
      private Vector obs;    //用来存储observer,用vector是因为其线程安全

      public Observable() {
          obs = new Vector();
     }

     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() {
         notifyObservers(null);
     }
     //此方法下文会具体详解
      public void notifyObservers(Object arg) {
         Object[] arrLocal;

         synchronized (this) {
             if (!changed)    
                 return;
             arrLocal = obs.toArray();  
             clearChanged();    
         }

         for (int i = arrLocal.length-1; i>=0; i--)
             ((Observer)arrLocal[i]).update(this, arg);
     }

     public synchronized void deleteObservers() {
         obs.removeAllElements();
     }

     protected synchronized void setChanged() {
         changed = true;
     }

     protected synchronized void clearChanged() {
         changed = false;
     }

     public synchronized boolean hasChanged() {
         return changed;
     }

     public synchronized int countObservers() {
         return obs.size();
     }
 }

其他函数没有什么好说的容易理解,重点看看public void notifyObservers(Object arg){};

 public void notifyObservers(Object arg) {

         Object[] arrLocal;
       /*对change加同步锁,防止多线程下各线程对changed变量的读写操作不安全
       可能出现脏读因此产生重复update或者不能update的情况*/
         synchronized (this) {
         //如果没有变化,直接返回
             if (!changed)    
                 return;
             arrLocal = obs.toArray();  
             //重置变化
             clearChanged();    
         }
         //循环通知更新
         for (int i = arrLocal.length-1; i>=0; i--)
             ((Observer)arrLocal[i]).update(this, arg);
     }

这段代码可以说设计的很巧妙了,首先就是同步锁,没有加在方法上,而是只加在了change这部分上,是因为只要不会引起变量状态的不一致性就行了,同时当同步块的代码执行完毕后,该线程可以先去执行耗时的for循环。避免了将循环放进同步方法中,如果并发量是十几二十的时候,就会特别耗时了。还有一个设计的很好的地方我觉得是Object[] arrLocal;源码中,没有选择直接操作obs,而是在同步方法中再保存了一次,这样更大程度上确保了观察者列表的线程安全,因为如果直接操作obs的话可能obs在其他线程中已经更新或者变化了。而复制一份就不一样了。这有点类似原型模式中的保护性克隆,为了防止这个只读对象被修改,通常可以通过返回给一个对象的拷贝的形式实现。

缺陷

使用Observable时需要使用继承,由于java的类单继承性,如果你的类已经继承了一个类,将不能继承Observable来实现观察者模式,并且由于setChanged和clearChanged方法都是protected的,所以你也不能通过组合来完成观察者模式,当然你如果自己写一个那另说了。

训练YOLOv11 | Pytorch和Pycharm的安装教程适用W11系统(附详细的系统变量添加过程) 根据你之前下载的版本选择对应的选项即可,然后复制底下的绿色代码到Anaconda的命令行输入即可(这里要在你安装的python环境里进行安装,例如我的环境名字是PyTorch,那么就是activate PyTorch里进行安装)然后同之前一样会加载一会,然后会询问我们是否下载配件,我们输入Y等待即可(下载过程中我们要确保网络通常如果有波动可能会下载失败)。类似于我的电脑是Windows11选择上面红框内的选项即可点击后即下载,(注意这里下载的是zip文件)下载完成后复制下面几个文件。 阅读详情

相关推荐

ABAP 7.40+新语法实战:用VALUE和REDUCE五分钟搞定复杂内表统计

本文详细介绍了ABAP 7.40+新语法中的VALUE和REDUCE操作符,如何高效处理复杂内表统计任务。通过实战案例展示,这些新语法能将代码量减少70%以上,显著提升开发效率和可读性,特别适合大数据量下的销售数据分析、分组统计等场景。

weixin_27219587的博客 206

Java观察者模式

文章目录观察者模式(observer)一、概述1.使用的场景2.UML类图3.核心角色抽象被观察者角色:抽象观察者角色:具体被观察者角色:具体观察者角色:二、手动实现观察者模式1.定义抽象被观察者角色2.定义抽象观察者角色3.定义具体被观察者角色4.定义具体观察者角色5.测试三、Java内置观察者模式实现1.定义具体被观察者2.定义具体观察者3.测试四、开发中的常用场景: 观察者模式(observ...

Tang 1778

利用CubeMX复现正点原子TFTLCD驱动例程

①准备delay.c、delay.h、sys.c和sys.h四个文件。FMC的工作原理暂时先欠着,先记录一下CRUD的过程。这里我们使用的是BANK1 的第一个分区。点击 Configuration->FMC。②把fmc自动生成的代码注释掉一部分。配置参数如下图 17.5.1。③这个printf语句要屏蔽掉。选项卡之下配置相关参数。④整体代码,按需裁剪。

qq_59757948的博客 1612

【设计模式】观察者模式Observe(Java)

观察者模式定义了对象之间的一对多依赖,这样以来,当一个对象改变状态时,他的所有观察者都会收到通知并且自动更新。

鹏啊鹏 1683

FPGA实战:AXI BRAM Controller配置避坑指南(Vivado 2023版)

本文详细解析了Vivado 2023环境下AXI BRAM Controller的配置技巧与避坑指南,涵盖AXI4协议转换、BRAM地址空间配置、信号异常处理及突发传输优化等核心内容。针对写时序冲突、跨时钟域处理等常见问题提供实用解决方案,帮助开发者提升FPGA系统性能与稳定性。

q1w3e5r7t9y的博客 340

立创EDA手动拼板实战:当自带功能不够用,如何用‘复制粘贴’搞定异形拼版与特殊布局

本文详细介绍了立创EDA手动拼板技术在异形拼版与特殊布局中的应用实战。通过CTRL+SHIFT+V等核心操作技巧,解决混合尺寸拼板、特殊间距需求等复杂场景,提升PCB设计效率与灵活性,特别适合需要高精度控制的射频电路和医疗设备项目。

weixin_31967485的博客 386

机器人的活动范围

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子? 回溯: privat...

weixin_38168198的博客 334

新能源充电桩充电枪口标准

建立的标准确保了新能源汽车充电的安全性、兼容性和效率,促进了新能源汽车产业的发展。

网络安全的研究者、新能源行业的追求者 4686

【设计模式】Java 设计模式之观察者模式(Observer)

观察者模式是一种实现对象间一对多依赖关系的设计模式,它使得当对象状态改变时,其依赖的对象能够自动收到通知并更新。该模式通过降低对象间的耦合度,提高了系统的可维护性和可扩展性。在实际应用中,需要注意内存泄漏、循环引用和性能等问题,并可通过弱引用、消息队列等方式进行改进。与其他设计模式相比,观察者模式在事件驱动和广播通信方面具有优势。在现代框架和库中,常内置观察者模式的实现,方便开发者使用。以在线股票交易系统为例,观察者模式可实现股票价格变化和用户界面更新的解耦,提高系统的灵活性和可扩展性。总之,观察者模式是一

新手村长的专栏 1901

【CASS精品教程】032:CASS11台阶画法案例大全

一、普通无边台阶 二、普通有边台阶 三、普通圆弧无边台阶 四、U型台阶 五、曲线U型台阶 六、L型台阶

智慧空间实验室 7463

【华为OD机试真题 2025双机位A卷】958、 高效的任务规划 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

【华为OD机试真题 2025双机位A卷】958、 高效的任务规划 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2025e卷,od机试,2025E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2025华为od,

KJ.JK 1071

Java设计模式之一:观察者模式

Java设计模式之一:观察者模式

杨荧的优快云博客 1万+

2026华数杯 国际大学生数学建模竞赛 A题 如何防守直接任意球? 解题思路+模型分析+代码

2026华数杯 国际大学生数学建模竞赛 A题 如何防守直接任意球? 解题思路+模型分析+代码。基于视频数据重构进球轨迹,建立空间坐标系并进行曲线拟合,推算初始速度。建立"香蕉球"、"电梯球"、"落叶球"三种典型直接任意球轨迹的动力学模型,分析C罗进球的类型。针对C罗这类强力球员的直接任意球,提出人墙排布策略和守门员防守策略。

YOLO 663

【jdk源码解析一】java.util.Observer与java.util.Observable

观察者模式大家应该十分熟悉,贴一张别人的图如下: 上图十分清晰的展示了观察者模式是什么样的。在java的util包里,实际上有内置的对观察者模式的实现,java.uti.Observable类就是这里的主题,而Observer接口对应的就是Observer观察者接口。 但是,实际上,虽然java对Observable的实现不是使用接口来实现,因此,实际上并不是很符合设计模式的多用组合,

wqisen's workspace 1177

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

java.util 中Observer与Observable

Observer 观察者 Observer源码分析 package java.util; @Deprecated(since=&quot;9&quot;) public interface Observer { //只要改变了 observable 对象就调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,以 便向所有该对象的观察者通知此改变。 //参数: //...

大知无涯者 1384

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java设计模式(八)之观察者模式(Observer)

本文以JDK源码介绍。 观察者Observer public interface Observer { void update(Observable o, Object arg); } 被观察者Observable public class Observable { private boolean changed = false; private Vector<Observer> obs; public Observable() {...

L 448

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Android常见设计模式——观察者模式 (Observer Pattern)

文章目录1. 前言2. 观察者模式2.1 源码2.2 结构3. Android中的观察者模式 1. 前言 观察者模式是在代码框架中使用比较高的一个设计模式,常常又叫做订阅/发布模式。而通过这个设计模式通常我们就可以做到代码的解耦。 在现实生活中,比如当我们订阅了Android官方资讯后,用户就可以收到来自这些网站的推荐消息。在这个场景中就是发布/订阅模式。而这种观察行为通常是一个被观察者,多个观察者。通过观察者模式可以实现一种一对多的关系,使得当被观察者的状态发生改变的时候,所有的观察者都可以得到通知,并作

梦否 3555

观察者模式

一、概念 观察者模式又称为发布订阅模式,观察者模式定义了一对多的依赖关系,让多个观察者同时监视着被观察者的状态 二、简单实现观察者模式 被观察者需要继承Observable类 观察者需要实现Observer接口,实现upate方法 1、被观察者代码: import java.util.Observable; import java.util.Observer; public class Ob...

RuiDer的博客 371

观察者模式Observer及Java对此模式的支持

概念 观察者模式又叫发布-订阅模式(publish-subscribe)。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个 主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己。 结构分析 Subject(被观察对象接口): 规定ConcreteSubject的同意接口。 每个Subject可以有多个Observer。

chengmaoning的专栏 1118

Java 设计模式・观察者模式篇:从思想到代码实现

摘要:本文介绍了行为型设计模式中的观察者模式,通过微信公众号订阅的实例展示了该模式的实现方式。观察者模式实现对象间一对多的依赖关系,当被观察者状态变化时自动通知所有观察者。文章详细说明了模式角色(抽象/具体观察者、抽象/具体被观察者)、Java代码实现、优缺点分析及适用场景,并与发布-订阅模式进行对比。同时指出JDK中原生支持但已废弃的Observable/Observer实现,强调该模式在事件监听、状态同步等场景的应用价值。

l7_yuqi的博客 864

【java】 Observer和Observable详解

本文转自:【java】Observer和Observable详解 1.必要性 观察者模式是oo设计中经常用到的模式之一,大家在解决实际需求时,观察者模式往往都会用到,而javase中已经提供了Observer接口和Observable类让你简单快速的实现观察者模式,因此有必要去了解Observer和Observable; 2.观察者模式概述 下面先给出观察者模式标准版的定义。 定义:观察者模式(有...

我飞故我在的专栏 1033

Observer和Observable详解

1.必要性 观察者模式是oo设计中经常用到的模式之一,大家在解决实际需求时,观察者模式往往都会用到,而javase中已经提供了Observer接口和Observable类让你简单快速的实现观察者模式,因此有必要去了解Observer和Observable; 2.观察者模式概述 下面先给出观察者模式标准版的定义。 定义:观察者模式(有时又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者...

idncareo 805

Observer和Observable概述(附实例)

1.必要性 1.1观察者模式是oo设计中经常用到的模式之一,大家在解决实际需求时,观察者模式往往都会用到,而javase中已经提供了Observer接口和Observable类让你简单快速的实现观察者模式,因此有必要去了解Observer和Observable; 2.观察者模式概述 2.1 角色:被观察对象,观察者 2.2 关系: 1).被观察对象:观察者 = 1:n 2).被观察对象状态发生变化,会通知所有观察者,观察者将做出相应的反应 3.源码分析 3.1 Observer接口 Obser.

小石潭记丶 1311

java中的观察者模式使用——Observer和Observable

本文翻译java源码中对Observer和Observable的注解,介绍观察者使用过程。 1、Observer接口 用途:当一个类想要获得被观察对象变化的通知时,可以实现Observer接口。 主要方法:Observer接口只有一个方法,void update(Observable o, Object arg)。这个方法在被观察对象变化时,被自动调用。应用程序调用被观察者的notifyOb...

qq_39175089的博客 1058

java.util.Observable 和java.util.Observer的源码分析

对于观察者模式,其实Java已经为我们提供了已有的接口和类。Java中的订阅者(Subscribe,观察者)就是类java.util.Observer,java中的通知治者(Publish,发布者)就是java.util .Observable 使用步骤: 1)创建 被观察者对象Observable mObservable ,创建观察者对象Observer mObserver, 为被观察者...

luo_boke的博客 682

RxJava源码分析之Observable

在学习本篇之前,我们先来看几个概念: Observable,其英文翻译是可观察者的意思; Observer,其英文翻译是观察者的意思; 通过这两个概念我们就可以很清楚的明白它们是做什么用的了吧,下面我们来看下它们的使用: val observable:Observable<Int> = Observable.create(ObservableOnSubscribe<In...

张思聪的博客 441
上一篇: 设计模式之观察者模式总结
下一篇: Android 事件总线 EventBus入门及使用
HJsir
博客等级 码龄10年 19粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值