定義
一個對象池是一組已經初始化過且可以使用的對象的集合,池的用戶可以從池子中取得對象,對其進行操作處理,并在不需要時歸還給池子而非銷毀它。
若初始化、實例化的代價高,且有需求需要經常實例化,但每次實例化的數量較少的情況下,使用對象池可以獲得顯著的效能提升。從池子中取得對象的時間是可預測的,但新建一個實例所需的時間是不確定。
實現
1. Reusable - 對象池中的對象,通常實例化代價比較高。
2. Client - 使用一個對象的實例。
3. ReusablePool - 管理對象的實例化,回收和銷毀。
單個實例中主要的思想
1.一個棧,這里用stack
2.初始化方法,容器開啟的時候可以預先創建池
3.創建實例的方法
4.提供從池中獲得對象實例的方法
5.提供返回的方法,不返回后果很嚴重
6.控制請求等待時間的方法,過了一定的事件還沒獲得對象實例,就返回一個null指針
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
import java.util.Stack; @SuppressWarnings ( "unchecked" ) public class ObjectPool { public ObjectPool() { } private PoolParam poolParam; public void setPoolParam(PoolParam poolParam) { this .poolParam = poolParam; } // 當前總對象個數 private int currentNum = 0 ; private Class clazz; public void setClazz(Class clazz) { this .clazz = clazz; } // 棧,用來存放對象,模擬一個池 private Stack stack; public Stack getStack() { return stack; } public void setStack(Stack stack) { this .stack = stack; } // ................................................................. // 等待超時的記數變量 private int timeWait = 0 ; // ................................................................. // 創建對象池 public void initalPool(PoolParam poolParam, Class clazz) { this .setPoolParam(poolParam); this .setClazz(clazz); stack = new Stack(); stack.clear(); // System.out.println("obj..pool is initial..."); // 生成配置最小對象數,并壓入棧中 try { for ( int i = 0 ; i < poolParam.getMinObjectCount(); i++) { // 根據poolParam初始化對象池 stack.push(clazz.newInstance()); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } // 創建單個對象 private Object createObj(Class clazz) { Object obj = null ; try { obj = clazz.newInstance(); // System.out.println("a new one..."); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return obj; } // 對象池提供的get方法 public Object getInstance(){ // System.out.println(stack.size()); Object object = null ; if (stack.size() == 0 ) { // 如果當前棧的長度為0,并且總的對象數沒有超過定義最大數 if ((currentNum + poolParam.getMinObjectCount()) < poolParam .getMaxObjectCount()) { // 新創建一個對象 object = this .createObj(clazz); // 對象數+1 currentNum++; } else { synchronized ( this ) { try { waitme( this ); } catch (Exception e) { e.printStackTrace(); } // 獲得通知后檢測棧中是為空,并給出剛剛釋放的資源 if (!stack.empty()) { object = stack.pop(); } } } } else if (stack.size() > 0 ) { object = stack.pop(); // System.out.println(stack.size()); } return object; } // 返回對象的方法 public void returnObj(Object obj) { if (clazz.isInstance(obj)) { stack.push(obj); synchronized ( this ) { notify(); } } else { System.out.println( "this object can not push to stack!" ); } } // 等待遞歸算法 private void waitme(ObjectPool pool) { // 等待2s的技術控制 if (timeWait >= 2000 ) { System.out.println( "jump up this step.." ); timeWait = 0 ; return ; } else { try { pool.wait( 500 ); // 等待計數累加。。 timeWait += 1000 ; System.out.println( "waiting time to free obj.." ); if (stack.empty()) { System.out.println( "agian...." ); waitme(pool); } } catch (InterruptedException e) { e.printStackTrace(); } } } } |
管理池類,這個不是很難,同步了就好
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
|
@SuppressWarnings ( "unchecked" ) public class ObjectPoolManage { private ObjectPoolManage() { } private static ObjectPool pool; // 實現一個單例的獲取方法....默認 public static synchronized ObjectPool getCacheObject(Class clazz) { if ( null != pool) { return pool; } else { createObjectPool( null , clazz); return pool; } } // 實現一個單例的獲取方法...自定義 public static synchronized ObjectPool getCacheObject(PoolParam p, Class clazz) { if ( null != pool) { return pool; } else { createObjectPool(p, clazz); return pool; } } private static ObjectPool createObjectPool(PoolParam p, Class clazz) { pool = new ObjectPool(); if ( null == p) { pool.initalPool( new PoolParam( 5 , 10 ), clazz); } else { pool.initalPool(p, clazz); } return pool; } private static Class getclazz(){ Class clazz= null ; try { clazz= Class.forName(ppp.getPropertyByName( "objectPath" )); } catch (ClassNotFoundException e) { e.printStackTrace(); } return clazz; } } |
相關問題和實現
1. 對象池中可以限制對象的個數,當超過限制時,對象池需要返回異常或者空值,以通知客戶。
2. 在多線程環境中,在checkout和checkin方法需要同步。
3. 定時清理過期的對象。