package com.glview.pool; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Pool<T extends Poolable> { private boolean mMultiple; private int mMaxPoolSize = -1; private Map<Class<? extends Poolable>, List<T>> mPoll = new HashMap<Class<? extends Poolable>, List<T>>(); private List<T> mSinglePool; public Pool(boolean multiple) { this(multiple, -1); } public Pool(boolean multiple, int maxPoolSize) { mMultiple = multiple; mMaxPoolSize = maxPoolSize; } public synchronized Poolable poll(Class<? extends Poolable> cls) { return poll(cls, true); } public synchronized Poolable poll(Class<? extends Poolable> cls, boolean autoCreate) { List<T> l = ensureTypeList(cls); Poolable poolable = l.size() > 0 ? l.remove(l.size() - 1) : null; if (poolable == null && autoCreate) { poolable = create(cls); } return poolable; } public synchronized boolean push(T poolable) { if (poolable == null) return false; List<T> l = ensureTypeList(poolable.getClass()); if (mMaxPoolSize > 0 && l.size() >= mMaxPoolSize) { return false; } l.add(poolable); return true; } public synchronized void recycle() { mPoll.clear(); } private List<T> ensureTypeList(Class<? extends Poolable> cls) { if (!mMultiple) { if (mSinglePool == null) { if (mMaxPoolSize > 0) { mSinglePool = new ArrayList<T>(mMaxPoolSize); } else { mSinglePool = new ArrayList<T>(); } } return mSinglePool; } List<T> l = mPoll.get(cls); if (l == null) { if (mMaxPoolSize > 0) { l = new ArrayList<T>(mMaxPoolSize); } else { l = new ArrayList<T>(); } mPoll.put(cls, l); } return l; } private Poolable create(Class<? extends Poolable> cls) { try { Constructor<?> c = cls.getConstructor(); c.setAccessible(true); return (Poolable) c.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } }