Glide--FactoryPools源码分析

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);
  }

分析完毕,将池与创建工厂,抽象,达到复用对象的代码编程模式简化。确实不错。

猜你喜欢

转载自blog.csdn.net/atxxiang4/article/details/85046429