1 19 package org.openharmonise.commons.pool; 20 21 import java.util.*; 22 import java.util.logging.*; 23 import java.util.logging.Logger ; 24 25 32 public abstract class AbstractPool { 33 34 37 private long expirationTime; 38 39 42 private long lastCheckOut; 43 44 47 private Map lockedMap; 48 49 52 private Map unlockedMap; 53 54 57 private CleanUpThread cleaner; 58 59 62 private int MIN_POOL = 0; 63 64 67 private static Logger m_logger = Logger.getLogger(AbstractPool.class.getName()); 68 69 72 public AbstractPool() { 73 expirationTime = (1000 * 300000); lockedMap = new Hashtable(); 75 unlockedMap = new Hashtable(); 76 lastCheckOut = System.currentTimeMillis(); 77 78 cleaner = new CleanUpThread(this, expirationTime); 79 cleaner.start(); 80 81 Object o; 83 84 try { 85 for (int i = 0; i < MIN_POOL; i++) { 86 o = create(); 87 88 unlockedMap.put(o, new TimestampedObject(o, 89 new Long (System.currentTimeMillis()))); 90 } 91 } catch (Exception e) { 92 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 93 } 94 } 95 96 102 abstract public Object create() throws Exception ; 103 104 110 abstract public boolean validate(Object o); 111 112 117 abstract public void expire(Object o); 118 119 124 public void setMinPoolSize(int num) { 125 MIN_POOL = num; 126 127 ensureMinPool(); 128 } 129 130 135 public synchronized int countObjects() { 136 return lockedMap.size() + unlockedMap.size(); 137 } 138 139 145 public synchronized Object checkOut() throws Exception { 146 long now = System.currentTimeMillis(); 147 lastCheckOut = now; 148 149 Object o; 150 TimestampedObject to; 151 synchronized (unlockedMap) { 152 synchronized (lockedMap) { 153 if (unlockedMap.size() > 0) { 154 boolean bFoundValid = false; 155 156 while ((bFoundValid == false) && (unlockedMap.size() > 0)) { 157 o = unlockedMap.keySet().iterator().next(); 158 159 if (validate(o)) { 160 bFoundValid = true; 161 lockedMap.put(o, unlockedMap.get(o)); 162 unlockedMap.remove(o); 163 164 m_logger.logp(Level.FINER, this.getClass().getName(), "checkOut", "Giving out object - " + 165 o.hashCode() ); 166 167 168 return o; 169 } else { 170 unlockedMap.remove(o); 171 expire(o); 172 to = null; 173 } 174 } 175 } 176 o = create(); 177 lockedMap.put(o,new TimestampedObject(o, new Long (now))); 178 } 179 } 180 181 ensureMinPool(); 182 183 return o; 184 } 185 186 191 public synchronized void checkIn(Object o) { 192 if (o != null) { 193 synchronized (unlockedMap) { 194 synchronized (lockedMap) { 195 196 197 m_logger.log(Level.FINER, "Checking in..." + o.hashCode()); 198 199 unlockedMap.put(o, lockedMap.get(o)); 200 lockedMap.remove(o); 201 } 202 } 203 } 204 } 205 206 209 synchronized void cleanUp() { 210 synchronized (unlockedMap) { 211 TimestampedObject to; 212 Object o; 213 ArrayList toRemove = new ArrayList(); 214 215 long now = System.currentTimeMillis(); 216 217 for (Iterator iter = unlockedMap.keySet().iterator(); 218 iter.hasNext(); 219 ) { 220 o = (Object ) iter.next(); 221 222 to = (TimestampedObject) unlockedMap.get(o); 223 224 if ((now - to.getTimestamp().longValue()) > expirationTime) { 225 toRemove.add(o); 227 expire(o); 228 } 229 } 230 231 for (Iterator iter = toRemove.iterator(); iter.hasNext();) { 232 Object obj = (Object ) iter.next(); 233 unlockedMap.remove(obj); 234 } 235 } 236 237 ensureMinPool(); 238 } 239 240 244 private void ensureMinPool() { 245 Object o; 246 synchronized (unlockedMap) { 247 if ((unlockedMap.size() + lockedMap.size()) < MIN_POOL) { 248 int num2add = MIN_POOL - unlockedMap.size(); 249 250 try { 251 for (int i = 0; i < num2add; i++) { 252 o = create(); 253 254 unlockedMap.put(o, new TimestampedObject(o, 255 new Long (System.currentTimeMillis()))); 256 257 } 258 } catch (Exception e) { 259 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 260 } 261 } 262 } 263 } 264 265 273 private class TimestampedObject { 274 277 private Object m_object; 278 281 private Long m_timestamp; 282 283 289 public TimestampedObject(Object obj, Long timestamp) { 290 m_timestamp = timestamp; 291 m_object = obj; 292 } 293 294 299 public Object getObject() { 300 return m_object; 301 } 302 303 308 public Long getTimestamp() { 309 return m_timestamp; 310 } 311 312 313 316 public boolean equals(Object obj) { 317 TimestampedObject to = (TimestampedObject) obj; 318 319 boolean bReturn = m_object.equals(to.getObject()); 320 321 return bReturn; 322 } 323 324 327 public String toString() { 328 return "(" + m_object.hashCode() + "," + m_timestamp + ")"; 329 } 330 } 331 } 332 333 341 class CleanUpThread extends Thread { 342 345 private AbstractPool pool; 346 349 private long sleepTime; 350 351 357 CleanUpThread(AbstractPool pool, long sleepTime) { 358 this.pool = pool; 359 this.sleepTime = sleepTime; 360 } 361 362 363 366 public void run() { 367 while (true) { 368 try { 369 sleep(sleepTime); 370 } catch (InterruptedException e) { 371 } 373 374 pool.cleanUp(); 375 } 376 } 377 } | Popular Tags |