池化技术
池化技术
单链表
Pools
Pools 总结
- 对象池缓存池,无需多线程同步用 SimplePool,需要多线程同步用
SynchronizedPool
- 对象缓存池用的是数组
- 从缓存中取对象和释放对象都是取/存数组中的最后一个
Pools 源码
Android 包 androidx.core.util
下有个工具类 Pools,为开发者提供了两种对象池,没有同步控制的 SimplePool 和 有同步控制(访问加锁)的 SynchronizedPool(继承自 SimplePool),方便开发者根据需要创建对应类型的对象池
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Pools androidx1.3.1
public final class Pools {
private Pools() {
}
// 对象池接口
public interface Pool<T> {
// 从池中获取一个对象,没有则返回null
@Nullable
// 释放对象,将对象放入对象池中,如果对象已经在池中类,会抛出IllegalStateException异常;成功释放(池中有多余的空间)返回true;否则,返回fals
T acquire();
boolean release(@NonNull T instance); // @throws IllegalStateException
}
/**
* 没有同步控制的简单对象池
*/
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;
}
}
/**
* 有同步控制(访问加锁)的对象池
*/
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);
}
}
}
}
系统类用到的示例
系统源码 Pools 使用
- Message
- MotionEvent,
- TouchTarget 等都是单链表的对象缓存池
- TabLayout.newTab
private static final
Pools.Pool<Tab>
tabPool = new Pools.SynchronizedPool<>(16);
VelocityTracker
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public final class VelocityTracker {
private static final SynchronizedPool<VelocityTracker> sPool =
new SynchronizedPool<VelocityTracker>(2);
static public VelocityTracker obtain() {
VelocityTracker instance = sPool.acquire();
return (instance != null) ? instance : new VelocityTracker(null);
}
public void recycle() {
if (mStrategy == null) {
clear();
sPool.release(this);
}
}
}
AsyncLayoutInflater
1
2
3
4
// AsyncLayoutInflater
private static class InflateThread extends Thread {
private Pools.SynchronizedPool<InflateRequest> mRequestPool = new Pools.SynchronizedPool(10);
}
案例
SynchronizedPool
SynchronizedPool 官方案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 官方例子
public class MyPooledClass {
private static final SynchronizedPool<MyPooledClass> sPool =
new SynchronizedPool<MyPooledClass>(10);
public static MyPooledClass obtain() {
MyPooledClass instance = sPool.acquire();
return (instance != null) ? instance : new MyPooledClass();
}
public void recycle() {
// 必要时,先重置状态
sPool.release(this);
}
// ...
}
SynchronizedPool 示例 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class PoolsDemo {
private String date;
private static final Pools.SynchronizedPool<PoolsDemo> sPool =
new Pools.SynchronizedPool<PoolsDemo>(5);
private PoolsDemo() {
date = DateUtils.formatDateToString(System.currentTimeMillis());
}
public static PoolsDemo obtain() {
PoolsDemo instance = sPool.acquire();
return (instance != null) ? instance : new PoolsDemo();
}
private void clear() {
// 如果需要,清理状态
}
public void recycle() {
// Clear state if needed.
this.clear();
sPool.release(this);
}
@Override
public String toString() {
return "PoolsDemo{" +
"date='" + date + '\'' +
'}';
}
}
ObjectPool
ObjectPool 提供了可回收对象的可能,系统 hide 的 API,在 Activity 生命周期用到了
ObjectPool 源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* An object pool that can provide reused objects if available.
* @hide
*/
class ObjectPool {
private static final Object sPoolSync = new Object();
private static final Map<Class, ArrayList<? extends ObjectPoolItem>> sPoolMap =
new HashMap<>();
private static final int MAX_POOL_SIZE = 50;
/**
* Obtain an instance of a specific class from the pool
* @param itemClass The class of the object we're looking for.
* @return An instance or null if there is none.
*/
public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) {
synchronized (sPoolSync) {
@SuppressWarnings("unchecked")
final ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(itemClass);
if (itemPool != null && !itemPool.isEmpty()) {
return itemPool.remove(itemPool.size() - 1);
}
return null;
}
}
/**
* Recycle the object to the pool. The object should be properly cleared before this.
* @param item The object to recycle.
* @see ObjectPoolItem#recycle()
*/
public static <T extends ObjectPoolItem> void recycle(T item) {
synchronized (sPoolSync) {
@SuppressWarnings("unchecked")
ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(item.getClass());
if (itemPool == null) {
itemPool = new ArrayList<>();
sPoolMap.put(item.getClass(), itemPool);
}
// Check if the item is already in the pool
final int size = itemPool.size();
for (int i = 0; i < size; i++) {
if (itemPool.get(i) == item) {
throw new IllegalStateException("Trying to recycle already recycled item");
}
}
if (size < MAX_POOL_SIZE) {
itemPool.add(item);
}
}
}
}
/**
* Base interface for all lifecycle items that can be put in object pool.
*
* @hide
*/
public interface ObjectPoolItem {
/**
* Clear the contents of the item and putting it to a pool. The implementation should call
* {@link ObjectPool#recycle(ObjectPoolItem)} passing itself.
*/
void recycle();
}
servertransaction 目录下的基本都用到了
- ActivityLifecycleItem
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
public class TestObjectPoolItem implements ObjectPoolItem {
private String date;
public TestObjectPoolItem() {
date = DateUtils.formatDateToString(System.currentTimeMillis());
}
@Override
public void recycle() {
date = "";
}
}
item = ObjectPool.obtain(TestObjectPoolItem::class.java)
ObjectPool.recycle(item)
本文由作者按照 CC BY 4.0 进行授权