通过 PoolObjectFactory 接口使用 Pool<T> class 进行实例化

Instantiating with a Pool<T> class via PoolObjectFactory interface

下面是使用 Java 池(泛型池)为 Android 实例化 TouchEvents 的示例:

import java.util.ArrayList;
import java.util.List;

public class Pool<T> {
    public interface PoolObjectFactory<T> {
        public T createObject();
    }

    private final List<T> freeObjects;
    private final PoolObjectFactory<T> factory;
    private final int maxSize;

    public Pool(PoolObjectFactory<T> factory, int maxSize) {
        this.factory = factory;
        this.maxSize = maxSize;
        this.freeObjects = new ArrayList<T>(maxSize);
    }

    public T newObject() {
        T object = null;

        if (freeObjects.isEmpty()) {
            object = factory.createObject();
        } else {
            object = freeObjects.remove(freeObjects.size() - 1);
        }

        return object;
    }

    public void free(T object) {
        if (freeObjects.size() < maxSize) {
            freeObjects.add(object);
        }
    }
}

但是,我不太明白这段代码是如何工作的:

if (freeObjects.isEmpty()) {
    object = factory.createObject();
} else {
    object = freeObjects.remove(freeObjects.size() - 1);
}

假设我们有:

touchEventPool = new Pool<TouchEvent>(factory, 100);

这是否意味着它要存储一个包含 100 个事件的数组(当 #101 进入时,将像先进先出一样处理掉 #1)?

我假设它应该容纳一些最大数量的对象,然后处理多余的对象。我读了书的描述大约 10 遍……但无法理解。也许有人解释这是如何工作的?

I assume it supposed to hold some maximum number of objects and then dispose the extra. I read book's description like 10 times.. and couldn't get it. Maybe someone explain how this works?

有点。 class 将预先创建的对象缓存在名为 poolList 中。当您请求一个新对象(通过 newObject 方法)时,它会首先检查 pool 以查看对象是否可用。如果池是空的,它只会创建一个对象并 return 发送给你。如果有对象可用,它会删除 pool 中的最后一个元素,然后 return 将其发送给您。

注释:

if (freeObjects.isEmpty()) {
    // The pool is empty, create a new object.
    object = factory.createObject();
} else {
    // The pool is non-empty, retrieve an object from the pool and return it.
    object = freeObjects.remove(freeObjects.size() - 1);
}

并且当您 return 一个对象到缓存(通过 free() 方法)时,只有在池的最大大小没有达到时它才会被放回池中。

注释:

public void free(T object) {
    // If the pool is not already at its maximum size.
    if (freeObjects.size() < maxSize) {
        // Then put the object into the pool.
        freeObjects.add(object);
    }
    // Otherwise, just ignore this call and let the object go out of scope.
}

如果池的最大大小已经达到,您正在释放的对象将不会被存储并且(可能)会受到垃圾回收的影响。

任何池的想法都是创建受控环境,当一些未使用的空闲实例可以从池中重新使用时,(通常)不需要创建新的(事件)实例。

当你创建 touchEventPool = new Pool<TouchEvent>(factory, 100); 您希望在节目直播的任何特定时刻 100 个实例就足够了。

因此,当您想要获取第 101 个事件时,该过程可能会释放前 5、20 甚至 99 个事件,并且池将能够重用它们中的任何一个。

如果没有空闲实例,则将根据池策略创建新实例,或者请求者线程将等待其他线程释放一个并 return 到池中。在这个特定的实现中,将创建新的。

我认为对象池的主要概念是减少对象实例化的频率。

Does this mean it is going to store an Array of 100 events (and when #101 comes inside, will dispose #1, like first-in-first-out)?Does this mean it is going to store an Array of 100 events (and when #101 comes inside, will dispose #1, like first-in-first-out)?

我不这么认为。最大数量 100 表示 freeObjects 但当前正在使用的对象。当一个对象不再被使用时,你应该释放它。然后释放的对象不会被丢弃,而是作为一个 freeObject 存储(最大数量意味着这些空闲对象的数量)。下次您需要另一个新对象时,您不必实例化一个新对象。您所需要的只是重用一个备用的 freeObjects。

因此您可以避免昂贵的对象实例化。它可以提高性能。