概述
Glide 中有池的概念,找到了工厂池这个类,我们着重分析,学习他的编程技巧。
public final class FactoryPools {
private static final String TAG = "FactoryPools";
private static final int DEFAULT_POOL_SIZE = 20;
private static final Resetter<Object> EMPTY_RESETTER = new Resetter<Object>() {
@Override
public void reset(Object object) {
// Do nothing.
}
};
private FactoryPools() { }
/**
* Returns a non-thread safe {@link Pool} that never returns {@code null} from
* {@link Pool#acquire()} and that contains objects of the type created by the given
* {@link Factory} with the given maximum size.
*
* <p>If the pool is empty when {@link Pool#acquire()} is called, the given {@link Factory} will
* be used to create a new instance.
*
* @param <T> The type of object the pool will contains.
*/
public static <T extends Poolable> Pool<T> simple(int size, Factory<T> factory) {
return build(new SimplePool<T>(size), factory);
}
/**
* Returns a new thread safe {@link Pool} that never returns {@code null} from
* {@link Pool#acquire()} and that contains objects of the type created by the given
* {@link Factory} with the given maximum size.
*
* <p>If the pool is empty when {@link Pool#acquire()} is called, the given {@link Factory} will
* be used to create a new instance.
*
* @param <T> The type of object the pool will contains.
*/
public static <T extends Poolable> Pool<T> threadSafe(int size, Factory<T> factory) {
return build(new SynchronizedPool<T>(size), factory);
}
/**
* Returns a new {@link Pool} that never returns {@code null} and that contains {@link List Lists}
* of a specific generic type with a standard maximum size of 20.
*
* <p>If the pool is empty when {@link Pool#acquire()} is called, a new {@link List} will be
* created.
*
* @param <T> The type of object that the {@link List Lists} will contain.
*/
public static <T> Pool<List<T>> threadSafeList() {
return threadSafeList(DEFAULT_POOL_SIZE);
}
/**
* Returns a new thread safe {@link Pool} that never returns {@code null} and that contains
* {@link List Lists} of a specific generic type with the given maximum size.
*
* <p>If the pool is empty when {@link Pool#acquire()} is called, a new {@link List} will be
* created.
*
* @param <T> The type of object that the {@link List Lists} will contain.
*/
public static <T> Pool<List<T>> threadSafeList(int size) {
return build(new SynchronizedPool<List<T>>(size), new Factory<List<T>>() {
@Override
public List<T> create() {
return new ArrayList<>();
}
}, new Resetter<List<T>>() {
@Override
public void reset(List<T> object) {
object.clear();
}
});
}
private static <T extends Poolable> Pool<T> build(Pool<T> pool, Factory<T> factory) {
return build(pool, factory, FactoryPools.<T>emptyResetter());
}
private static <T> Pool<T> build(Pool<T> pool, Factory<T> factory,
Resetter<T> resetter) {
return new FactoryPool<>(pool, factory, resetter);
}
@SuppressWarnings("unchecked")
private static <T> Resetter<T> emptyResetter() {
return (Resetter<T>) EMPTY_RESETTER;
}
/**
* Creates new instances of the given type.
*
* @param <T> The type of Object that will be created.
*/
public interface Factory<T> {
T create();
}
/**
* Resets state when objects are returned to the pool.
*
* @param <T> The type of Object that will be reset.
*/
public interface Resetter<T> {
void reset(T object);
}
/**
* Allows additional verification to catch errors caused by using objects while they are in
* an object pool.
*/
public interface Poolable {
StateVerifier getVerifier();
}
private static final class FactoryPool<T> implements Pool<T> {
private final Factory<T> factory;
private final Resetter<T> resetter;
private final Pool<T> pool;
FactoryPool(Pool<T> pool, Factory<T> factory, Resetter<T> resetter) {
this.pool = pool;
this.factory = factory;
this.resetter = resetter;
}
@Override
public T acquire() {
T result = pool.acquire();
if (result == null) {
result = factory.create();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Created new " + result.getClass());
}
}
if (result instanceof Poolable) {
((Poolable) result).getVerifier().setRecycled(false /*isRecycled*/);
}
return result;
}
@Override
public boolean release(T instance) {
if (instance instanceof Poolable) {
((Poolable) instance).getVerifier().setRecycled(true /*isRecycled*/);
}
resetter.reset(instance);
return pool.release(instance);
}
}
}
池数据默认20个
private static final int DEFAULT_POOL_SIZE = 20;
一个数据类重新放入池中,需要重置他的状态。抽象出一个Resetter范型接口,拥有一个reset方法,给池调用
/**
* Resets state when objects are returned to the pool.
*
* @param <T> The type of Object that will be reset.
*/
public interface Resetter<T> {
void reset(T object);
}
private static final Resetter<Object> EMPTY_RESETTER = new Resetter<Object>() {
@Override
public void reset(Object object) {
// Do nothing.
}
};
类型工厂接口,create方法创建范型对象
/**
* Creates new instances of the given type.
*
* @param <T> The type of Object that will be created.
*/
public interface Factory<T> {
T create();
}
先看另外一个Pools类。里面有个Pool范型接口,两个需实现的方法,请求与释放。一个简单的实现SimplePool类,mPool对象数组保存数据,三个方法1.acquire从数组中实例的末尾取一个, 2.release方法,放到数组实例的末尾 ,不能重复回收,isInPool会抛出异常,3.isInPool 循环遍历,引用对比。 SynchronizedPool继承SimplePool,内部有个lock对象,用synchronized代码段同步。
public final class Pools {
/**
* Interface for managing a pool of objects.
*
* @param <T> The pooled type.
*/
public interface Pool<T> {
/**
* @return An instance from the pool if such, null otherwise.
*/
@Nullable
T acquire();
/**
* Release an instance to the pool.
*
* @param instance The instance to release.
* @return Whether the instance was put in the pool.
*
* @throws IllegalStateException If the instance is already in the pool.
*/
boolean release(@NonNull T instance);
}
private Pools() {
/* do nothing - hiding constructor */
}
/**
* Simple (non-synchronized) pool of objects.
*
* @param <T> The pooled type.
*/
public static class SimplePool<T> implements Pool<T> {
private final Object[] mPool;
private int mPoolSize;
/**
* Creates a new instance.
*
* @param maxPoolSize The max pool size.
*
* @throws IllegalArgumentException If the max pool size is less than zero.
*/
public SimplePool(int maxPoolSize) {
if (maxPoolSize <= 0) {
throw new IllegalArgumentException("The max pool size must be > 0");
}
mPool = new Object[maxPoolSize];
}
@Override
@SuppressWarnings("unchecked")
public T acquire() {
if (mPoolSize > 0) {
final int lastPooledIndex = mPoolSize - 1;
T instance = (T) mPool[lastPooledIndex];
mPool[lastPooledIndex] = null;
mPoolSize--;
return instance;
}
return null;
}
@Override
public boolean release(@NonNull T instance) {
if (isInPool(instance)) {
throw new IllegalStateException("Already in the pool!");
}
if (mPoolSize < mPool.length) {
mPool[mPoolSize] = instance;
mPoolSize++;
return true;
}
return false;
}
private boolean isInPool(@NonNull T instance) {
for (int i = 0; i < mPoolSize; i++) {
if (mPool[i] == instance) {
return true;
}
}
return false;
}
}
/**
* Synchronized) pool of objects.
*
* @param <T> The pooled type.
*/
public static class SynchronizedPool<T> extends SimplePool<T> {
private final Object mLock = new Object();
/**
* Creates a new instance.
*
* @param maxPoolSize The max pool size.
*
* @throws IllegalArgumentException If the max pool size is less than zero.
*/
public SynchronizedPool(int maxPoolSize) {
super(maxPoolSize);
}
@Override
public T acquire() {
synchronized (mLock) {
return super.acquire();
}
}
@Override
public boolean release(@NonNull T element) {
synchronized (mLock) {
return super.release(element);
}
}
}
}
字面翻译可池的,其实就是可以被回收利用的。。。
public interface Poolable {
StateVerifier getVerifier();
}
状态确认类,就一个字段isReleased,基本逻辑就是假如已经被回收了的使用就报错
public abstract class StateVerifier {
private static final boolean DEBUG = false;
public static StateVerifier newInstance() {
if (DEBUG) {
return new DebugStateVerifier();
} else {
return new DefaultStateVerifier();
}
}
private StateVerifier() { }
public abstract void throwIfRecycled();
abstract void setRecycled(boolean isRecycled);
private static class DefaultStateVerifier extends StateVerifier {
private volatile boolean isReleased;
@Synthetic
DefaultStateVerifier() { }
@Override
public void throwIfRecycled() {
if (isReleased) {
throw new IllegalStateException("Already released");
}
}
@Override
public void setRecycled(boolean isRecycled) {
this.isReleased = isRecycled;
}
}
private static class DebugStateVerifier extends StateVerifier {
private volatile RuntimeException recycledAtStackTraceException;
@Synthetic
DebugStateVerifier() { }
@Override
public void throwIfRecycled() {
if (recycledAtStackTraceException != null) {
throw new IllegalStateException("Already released", recycledAtStackTraceException);
}
}
@Override
void setRecycled(boolean isRecycled) {
if (isRecycled) {
this.recycledAtStackTraceException = new RuntimeException("Released");
} else {
this.recycledAtStackTraceException = null;
}
}
}
}
FactoryPool范型类实现于池接口,构造函数参数三个,池, 工厂,reset对象 1.acquire 方法逻辑是先在池里取,池没有,就用工厂方法创建,如果是可池化的对象,就设置回收状态为false. 2.release方法,将待回收对象,如果是可池化的,设置他的验证类回收状态为true,然后对象状态reset,最后放回池中
private static final class FactoryPool<T> implements Pool<T> {
private final Factory<T> factory;
private final Resetter<T> resetter;
private final Pool<T> pool;
FactoryPool(Pool<T> pool, Factory<T> factory, Resetter<T> resetter) {
this.pool = pool;
this.factory = factory;
this.resetter = resetter;
}
@Override
public T acquire() {
T result = pool.acquire();
if (result == null) {
result = factory.create();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Created new " + result.getClass());
}
}
if (result instanceof Poolable) {
((Poolable) result).getVerifier().setRecycled(false /*isRecycled*/);
}
return result;
}
@Override
public boolean release(T instance) {
if (instance instanceof Poolable) {
((Poolable) instance).getVerifier().setRecycled(true /*isRecycled*/);
}
resetter.reset(instance);
return pool.release(instance);
}
}
有些对象回收时候不需要先重置状态再放入池中,所以就什么都不做。
private static <T> Resetter<T> emptyResetter() {
return (Resetter<T>) EMPTY_RESETTER;
}
两个build方法返回FactoryPool,就是带回收池的工厂。提高复用对象,增强性能,比如android message回收复用那块写的就不如这个。
private static <T extends Poolable> Pool<T> build(Pool<T> pool, Factory<T> factory) {
return build(pool, factory, FactoryPools.<T>emptyResetter());
}
private static <T> Pool<T> build(Pool<T> pool, Factory<T> factory,
Resetter<T> resetter) {
return new FactoryPool<>(pool, factory, resetter);
}
这里有个例子,创建一个可回收的且线程安全ArrayList 的池。可以看到build方法中的参数用SynchronizedPool,匿名对象Factory中的实现 1.create 创建ArrayList, 2.reset 方法,清空ArrayList
public static <T> Pool<List<T>> threadSafeList() {
return threadSafeList(DEFAULT_POOL_SIZE);
}
public static <T> Pool<List<T>> threadSafeList(int size) {
return build(new SynchronizedPool<List<T>>(size), new Factory<List<T>>() {
@Override
public List<T> create() {
return new ArrayList<>();
}
}, new Resetter<List<T>>() {
@Override
public void reset(List<T> object) {
object.clear();
}
});
}
给用户两个选项,创建简单的不同步的池,或者创建同步池。按需调用
public static <T extends Poolable> Pool<T> simple(int size, Factory<T> factory) {
return build(new SimplePool<T>(size), factory);
}
public static <T extends Poolable> Pool<T> threadSafe(int size, Factory<T> factory) {
return build(new SynchronizedPool<T>(size), factory);
}
分析完毕,将池与创建工厂,抽象,达到复用对象的代码编程模式简化。确实不错。
最后
以上就是健康小蚂蚁为你收集整理的Glide--FactoryPools源码分析的全部内容,希望文章能够帮你解决Glide--FactoryPools源码分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复