Glide 中有池的概念,找到了工厂池这个类,我们着重分析,学习他的编程技巧。

public final class FactoryPools {
  private static final String TAG = \"FactoryPools\";
  private static final int DEFAULT_POOL_SIZE = 20;
  private static final Resetter< > EMPTY_RESETTER = new Resetter< >() {
    @Override
    public void reset(   ) {
      // Do nothing.
    }
  };

  private FactoryPools() { }

  /**
   * Returns a non-thread safe {@  Pool} that never returns {@code null} from
   * {@  Pool#acquire()} and that contains  s of the type created by the given
   * {@  Factory} with the given maximum size.
   *
   * <p>If the pool is empty when {@  Pool#acquire()} is called, the given {@  Factory} will
   * be used to create a new instance.
   *
   * @param <T> The type of   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 {@  Pool} that never returns {@code null} from
   * {@  Pool#acquire()} and that contains  s of the type created by the given
   * {@  Factory} with the given maximum size.
   *
   * <p>If the pool is empty when {@  Pool#acquire()} is called, the given {@  Factory} will
   * be used to create a new instance.
   *
   * @param <T> The type of   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 {@  Pool} that never returns {@code null} and that contains {@  List Lists}
   * of a specific generic type with a standard maximum size of 20.
   *
   * <p>If the pool is empty when {@  Pool#acquire()} is called, a new {@  List} will be
   * created.
   *
   * @param <T> The type of   that the {@  List Lists} will contain.
   */
  public static <T> Pool<List<T>> threadSafeList() {
    return threadSafeList(DEFAULT_POOL_SIZE);
  }

  /**
   * Returns a new thread safe {@  Pool} that never returns {@code null} and that contains
   * {@  List Lists} of a specific generic type with the given maximum size.
   *
   * <p>If the pool is empty when {@  Pool#acquire()} is called, a new {@  List} will be
   * created.
   *
   * @param <T> The type of   that the {@  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>  ) {
         .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   that will be created.
   */
  public interface Factory<T> {
    T create();
  }

  /**
   * Resets state when  s are returned to the pool.
   *
   * @param <T> The type of   that will be reset.
   */
  public interface Resetter<T> {
    void reset(T  );
  }

  /**
   * Allows additional verification to catch errors caused by using  s while they are in
   * an   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  s are returned to the pool.
   *
   * @param <T> The type of   that will be reset.
   */
  public interface Resetter<T> {
    void reset(T  );
  }
  
 private static final Resetter< > EMPTY_RESETTER = new Resetter< >() {
    @Override
    public void reset(   ) {
      // Do nothing.
    }
  };

类型工厂接口,create方法创建范型对象

  /**
   * Creates new instances of the given type.
   *
   * @param <T> The type of   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  s.
     *
     * @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  s.
     *
     * @param <T> The pooled type.
     */
    public static class SimplePool<T> implements Pool<T> {
        private final  [] 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  [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  s.
     *
     * @param <T> The pooled type.
     */
    public static class SynchronizedPool<T> extends SimplePool<T> {
        private final   mLock = new  ();

        /**
         * 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

					
				
收藏 打印
您的足迹: