zoukankan      html  css  js  c++  java
  • 观察者模式JDK源码解析

    由于JDK中为了方便开发人员,已经写好了现成的观察者接口和被观察者类。

    先来观察者接口:

    //观察者接口,每一个观察者都必须实现这个接口
    public interface Observer {
        //这个方法是观察者在观察对象产生变化时所做的响应动作,从中传入了观察的对象和一个预留参数
        void update(Observable o, Object arg);
    
    }

     下面是被观察者类:

    import java.util.Vector;
    
    //被观察者类
    public class Observable {
        //这是一个改变标识,来标记该被观察者有没有改变
        private boolean changed = false;
        //持有一个观察者列表
        private Vector obs;
        
        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);
        }
        //notifyObservers(Object arg)的重载方法
        public void notifyObservers() {
        notifyObservers(null);
        }
        //通知所有观察者,被观察者改变了,你可以执行你的update方法了。
        public void notifyObservers(Object arg) {
            //一个临时的数组,用于并发访问被观察者时,留住观察者列表的当前状态,这种处理方式其实也算是一种设计模式,即备忘录模式。
            Object[] arrLocal;
        //注意这个同步块,它表示在获取观察者列表时,该对象是被锁定的
        //也就是说,在我获取到观察者列表之前,不允许其他线程改变观察者列表
        synchronized (this) {
            //如果没变化直接返回
            if (!changed)
                    return;
                //这里将当前的观察者列表放入临时数组
                arrLocal = obs.toArray();
                //将改变标识重新置回未改变
                clearChanged();
            }
            //注意这个for循环没有在同步块,此时已经释放了被观察者的锁,其他线程可以改变观察者列表
            //但是这并不影响我们当前进行的操作,因为我们已经将观察者列表复制到临时数组
            //在通知时我们只通知数组中的观察者,当前删除和添加观察者,都不会影响我们通知的对象
            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();
        }
    }

        

  • 相关阅读:
    【转载】VM Role实战: Azure 平台上传虚拟机C 盘不能大于64GB
    Asp.Net MVC项目编译View
    Notepad测试数据库连接
    【转载】使用远程桌面Remote desktop访问Azure虚拟机
    【转载】Azure Blob Storage 云存储中实现大文件分块断点续传
    jQuery Mobile 笔记(1) jQuery Mobile页面结构
    【转载】使用Azure SDK 1.6 ,VM Role里加载Azure Drive方案
    大把大把的时间 你要怎么把握啊
    asp.net 本质论学习
    在客户端用javascript或VBSCRIPT生成WORD文档(转)
  • 原文地址:https://www.cnblogs.com/yzf666/p/6564603.html
Copyright © 2011-2022 走看看