享元设计模式的定义:
使共享对象可有效的支持大量的细粒度的对象,核心就是对象复用。
对象的复用,比较常用两种方法是:一:根据HashMap进行对象的复用,二:根据对象池进行复用。
享元设计模式的举例
返回购票的价格对象
在做高铁火车时,不同的路段返回不同的价格,但是相同的路段的价格是一样的,我们就可以为查询相同路径的人共同返回一个价格的复用对象,不用每次都创建一个新的对象.。使用hashMap的方法。
1.创建返回价格的对象
public class Ticket {
String from;
String to;
int getPirce(){
return new Random().nextInt(100)+20;
}
public Ticket (String form,String to){
this.from = form;
this.to = to;
}
}
2。利用工厂模式创建不同的价格对象
用hashMap存储不同的路径的价格对象
public class TicketFactory {
static Map<String, Ticket> sTicketMap = new HashMap<>();
public static Ticket getTicket(String form, String to) {
String key = form + "-" + to;
Ticket ticket = sTicketMap.get(key);
if (ticket != null) {
return ticket;
}
ticket = new Ticket(form, to);
sTicketMap.put(key, ticket);
return ticket;
}
}
3.客户端的请求
public static void main(String[] argss){
for (int i= 0;i<1000;i++){
Ticket ticket = TicketFactory.getTicket("深圳","北京");
}
}
Message的对象复用
在Handler发送消息时我们会用到Message对象来发送消息。
我们一般会使用第二种,复用对象的创建方式:
Message message = new Message();
Message message1 = Message.obtain();
来看看Message.obtain()是怎样对象复用的?
// Message是一个有next的链表组成,sPool 就是复用的Message链表
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool; //拿到第一个msg
sPool = m.next; //将sPool 移到第二个msg
m.next = null; //将第一个的msg的next制空
m.flags = 0; // clear in-use flag
sPoolSize--; //复用对象大小-1
return m; //返回第一个复用对象
}
}
return new Message(); //否则创建新的msg
}
那看看Message又是怎么回收的
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 = UID_NONE;
workSourceUid = UID_NONE;
when = 0;
target = null;
callback = null;
data = null;
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool; //将要回收的Msg的next变成sPool
sPool = this; //sPool 移动到第一个msg
sPoolSize++;//大小+1
}
}
}
LayoutInflater创建控件时,也会复用控件的构造参数对象
网友评论