1. 對象池
當調用對象時,不使用常規的new 構造子的方式,而是通過一 個對象池操作。即如果池中存在該對象,則取出;如果不存在,則 新建一個對象並存儲在池中。當使用完該對象後,則將該對象的歸 還給對象池。
這裡會存在幾個問題,必須注意。
Tips 1,考慮多線程狀態下的存取對象;
Tips 2,考慮將對象池目錄表設計為Singleton模式,這樣使得 內存中僅存在唯一的一份緩存對象的表。
2.對象單元設計
每個對象單元指定一種類型的對象,由Class<T> type維 護。對象單元有兩個List,List<T> items用於存放該類型 的同類對象,List<Boolean> checkedOut用於指定當前是否 可用。
設置信號量int semaphore,當semaphore < items.size() 說明目前List中還有“空閒”的對象。每次取出對象後需 semaphore++,歸還對象後需semaphore--。
對象單元ObjectUnit.java
import java.util.ArrayList;
import java.util.List;
public class ObjectUnit<T> {
private Class<T> type;
private List<T> items = new ArrayList<T>();
private List<Boolean> checkedOut = new ArrayList<Boolean>();
private int semaphore;
public ObjectUnit(Class<T> type) {
this.type = type;
}
public synchronized T addItem() {
T obj;
try {
obj = type.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
items.add(obj);
checkedOut.add(false);
return obj;
}
public synchronized T checkOut() {
if (semaphore < items.size()) {
semaphore++;
return getItem();
} else
return addItem();
}
public synchronized void checkIn(T x) {
if (releaseItem(x))
semaphore--;
}
private synchronized T getItem() {
for (int index = 0; index < checkedOut.size(); index++)
if (!checkedOut.get(index)) {
checkedOut.set(index, true);
return items.get(index);
}
return null;
}
private synchronized boolean releaseItem(T item) {
int index = items.indexOf(item);
if (index == -1)
return false; // Not in the list
if (checkedOut.get(index)) {
checkedOut.set(index, false);
return true;
}
return false;
}
}
3.對象池目錄表設計
使用Map<Class<?>, ObjectUnit<?>>來保 存當前對象池中類型目錄,並把它設計為線程安全的 ConcurrentHashMap。
這裡的getObj方法和renObj方法不用加鎖,因為它調用的對象 單元類是線程安全的,並且Map是線程安全的。
此外,這裡在處理泛型的時候,會有warning產生,因為之前定 義Map中使用<?>,而後面的兩個泛型方法指定<T>。 還沒有想到更好的解決辦法。
Provider.java
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Provider {
private Map<Class<?>, ObjectUnit<? >> providers = new ConcurrentHashMap<Class<? >, ObjectUnit<?>>();
private static Provider instance = new Provider ();
private Provider() {
}
public static Provider getInstance() {
return instance;
}
@SuppressWarnings("unchecked")
public <T> T getObj(Class<T> key) {
ObjectUnit value = providers.get(key);
if (value != null) {
return (T) value.checkOut();
} else {
value = new ObjectUnit<T>(key);
providers.put(key, value);
return (T) value.addItem();
}
}
@SuppressWarnings("unchecked")
public <T> void renObj(T x) {
if (providers.containsKey(x.getClass())) {
ObjectUnit value = providers.get(x.getClass ());
value.checkIn(x);
}
}
}
本文出自 “子 孑” 博客,請務必保留此出處
http://zhangjunhd.blog.51cto.com/113473/66059