1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool.impl;
18
19 import java.lang.ref.SoftReference;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.NoSuchElementException;
24
25 import org.apache.commons.pool.BaseObjectPool;
26 import org.apache.commons.pool.ObjectPool;
27 import org.apache.commons.pool.PoolableObjectFactory;
28
29 /***
30 * A {@link java.lang.ref.SoftReference SoftReference} based
31 * {@link ObjectPool}.
32 *
33 * @author Rodney Waldhoff
34 * @version $Revision: 383290 $ $Date: 2006-03-05 02:00:15 -0500 (Sun, 05 Mar 2006) $
35 */
36 public class SoftReferenceObjectPool extends BaseObjectPool implements ObjectPool {
37 public SoftReferenceObjectPool() {
38 _pool = new ArrayList();
39 _factory = null;
40 }
41
42 public SoftReferenceObjectPool(PoolableObjectFactory factory) {
43 _pool = new ArrayList();
44 _factory = factory;
45 }
46
47 public SoftReferenceObjectPool(PoolableObjectFactory factory, int initSize) throws Exception {
48 _pool = new ArrayList();
49 _factory = factory;
50 if(null != _factory) {
51 for(int i=0;i<initSize;i++) {
52 Object obj = _factory.makeObject();
53 _factory.passivateObject(obj);
54 _pool.add(new SoftReference(obj));
55 }
56 }
57 }
58
59 public synchronized Object borrowObject() throws Exception {
60 assertOpen();
61 Object obj = null;
62 while(null == obj) {
63 if(_pool.isEmpty()) {
64 if(null == _factory) {
65 throw new NoSuchElementException();
66 } else {
67 obj = _factory.makeObject();
68 }
69 } else {
70 SoftReference ref = (SoftReference)(_pool.remove(_pool.size() - 1));
71 obj = ref.get();
72 }
73 if(null != _factory && null != obj) {
74 _factory.activateObject(obj);
75 }
76 if (null != _factory && null != obj && !_factory.validateObject(obj)) {
77 _factory.destroyObject(obj);
78 obj = null;
79 }
80 }
81 _numActive++;
82 return obj;
83 }
84
85 public synchronized void returnObject(Object obj) throws Exception {
86 assertOpen();
87 boolean success = true;
88 if(!(_factory.validateObject(obj))) {
89 success = false;
90 } else {
91 try {
92 _factory.passivateObject(obj);
93 } catch(Exception e) {
94 success = false;
95 }
96 }
97
98 boolean shouldDestroy = !success;
99 _numActive--;
100 if(success) {
101 _pool.add(new SoftReference(obj));
102 }
103 notifyAll();
104
105 if(shouldDestroy) {
106 try {
107 _factory.destroyObject(obj);
108 } catch(Exception e) {
109
110 }
111 }
112
113 }
114
115 public synchronized void invalidateObject(Object obj) throws Exception {
116 assertOpen();
117 _numActive--;
118 _factory.destroyObject(obj);
119 notifyAll();
120 }
121
122 /***
123 * Create an object, and place it into the pool.
124 * addObject() is useful for "pre-loading" a pool with idle objects.
125 */
126 public synchronized void addObject() throws Exception {
127 assertOpen();
128 Object obj = _factory.makeObject();
129 _numActive++;
130 returnObject(obj);
131 }
132
133 /*** Returns an approximation not less than the of the number of idle instances in the pool. */
134 public synchronized int getNumIdle() {
135 assertOpen();
136 return _pool.size();
137 }
138
139 public synchronized int getNumActive() {
140 assertOpen();
141 return _numActive;
142 }
143
144 public synchronized void clear() {
145 assertOpen();
146 if(null != _factory) {
147 Iterator iter = _pool.iterator();
148 while(iter.hasNext()) {
149 try {
150 Object obj = ((SoftReference)iter.next()).get();
151 if(null != obj) {
152 _factory.destroyObject(obj);
153 }
154 } catch(Exception e) {
155
156 }
157 }
158 }
159 _pool.clear();
160 }
161
162 public synchronized void close() throws Exception {
163 clear();
164 _pool = null;
165 _factory = null;
166 super.close();
167 }
168
169 public synchronized void setFactory(PoolableObjectFactory factory) throws IllegalStateException {
170 assertOpen();
171 if(0 < getNumActive()) {
172 throw new IllegalStateException("Objects are already active");
173 } else {
174 clear();
175 _factory = factory;
176 }
177 }
178
179 /*** My pool. */
180 private List _pool = null;
181
182 /*** My {@link PoolableObjectFactory}. */
183 private PoolableObjectFactory _factory = null;
184
185 /*** Number of active objects. */
186 private int _numActive = 0;
187 }