对象共享避免创建多对象享元模式-- 笔记

享元模式

是对象池的一种实现,Flyweight用来减少内存使用量,它设用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象共享、避免创建过多的对象的效果。

String类也有这种常量池技术!
感觉类似工厂, 用容器存储要使用的对象,如果创建过就从容器中取 ,避免内存移除。

Android源码中的享元设计模式

message.obtain(); 
Handler中的消息池  存储容器是单链表o
  Message obtain(){
if(sPool!=null){
Message m=sPool;
sPool=m.next;
m.next=null;
m.flags=0;
sPoolSize--;
return m;
}
return new Message();
}
每个Message都有一个同类型的next字段,这个next指向下一个可用的message,最后一个可用的Message的next则为空。
obtain()方法中只看到了从链表中获取对象,并没有看到存储到链表中,查看Message类说明时发现 
 which will pull  * them from a pool of recycled objects.原来创建的时候不会把Message对象放到池中在回收时才会
搜索后发现
public void recycle() {
    if (isInUse()) {//判断消息是否在使用
        if (gCheckRecycle) {
            throw new IllegalStateException("This message cannot be recycled because it "
                    + "is still in use.");
        }
        return;
    }
    //清空状态并把消息添加到池中
    recycleUnchecked();
}
void recycleUnchecked() {
    // Mark the message as in use while it remains in the recycled object pool.
    // Clear out all other details.
    flags = FLAG_IN_USE;
    what = 0;
    arg1 = 0;
    arg2 = 0;
    obj = null;
    replyTo = null;
    sendingUid = -1;
    when = 0;
    target = null;
    callback = null;
    data = null;
    //回收消息到消息池
    synchronized (sPoolSync) {
        if (sPoolSize < MAX_POOL_SIZE) {
            next = sPool;
            sPool = this;
            sPoolSize++;
        }
    }
}
插入数据方式是从链表中插入表头 链表size++
取Message方式是取表头 表头指针sPool 指向下一个节点 size--
这里并不是经典的实现方式,它没有内部、外部状态,集各个职责于一身,更像一个对象池。灵活运用模式解决问题。
规则很多时候并不是一成 不变的。

规则是使读者避免走向软件大泥潭,灵活应用才是最终的目的所在。

深入扩展

Android程序的入口实际上是ActivityThread的mian方法 首先会创建Application和默认启动的Activity
ActivityThread.main
public static void main(String[] args) {
  
    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}


你可能感兴趣的:(对象共享避免创建多对象享元模式-- 笔记)