享元模式的目的就是达到充分利用已有的对象,避免创建过多对象的效果,从而提升性能,减少内存消耗。 通过Android中的消息机制来体会这种设计: - Message的使用 当我们创建一个 Message 时,推荐使用 Message.obtain() 。我们看看其实现:
public static Message obtain(){ synchronized(sPoolSync){ if(sPool != null){ Message m = sPool; sPool = m.next; m.next = null; //清空in-use flag m.flags = 0; sPoolSize--; return m; } } return new Message();}从这段代码中我们就可以看出来Message的实现是通过链表来实现的!!通过Message的next字段将所有可用的Message串连成一个可用的Message池。sPool即为这个链表的头指针。 而在Message中还有这两个方法:
/*** 将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(){ //清空消息状态,设置该消息 in-use flag //FLAG_IN_USE 表示该消息已被使用 //obtain()函数中置0,根据该字段即可追踪消息的状态 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){ //消息插入表头 nex = sPool; sPool = this; sPoolSize++; } }}由此可见,消息在创建的时候并不会把Message对象放到池中,而是在回收(并不是虚拟机的回收)该对象时将其插入链表。类似Bitmap的recycle()函数。 通过链表来维护一个Message池,即可实现对象的重用。
新闻热点
疑难解答