001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/framework/util/ObjectPool.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.framework.util; 037 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.util.ArrayList; 041 import java.util.Collections; 042 import java.util.HashMap; 043 import java.util.List; 044 import java.util.Map; 045 import java.util.Properties; 046 import java.util.Timer; 047 import java.util.TimerTask; 048 049 import org.deegree.framework.log.ILogger; 050 import org.deegree.framework.log.LoggerFactory; 051 052 /** 053 * class to manage the object pool. this is part of the combination of the object pool pattern an the singelton pattern. 054 * 055 * @version $Revision: 20107 $ 056 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 057 * @author last edited by: $Author: aschmitz $ 058 * 059 * @version $Revision: 20107 $, $Date: 2009-10-13 13:15:16 +0200 (Di, 13 Okt 2009) $ 060 */ 061 public abstract class ObjectPool extends TimerTask { 062 063 private static final ILogger LOG = LoggerFactory.getLogger( ObjectPool.class ); 064 065 /** 066 * all available objects 067 */ 068 protected List<Object> available = null; 069 070 /** 071 * all objects in use 072 */ 073 protected List<Object> in_use = null; 074 075 /** 076 * the start life time for each object 077 */ 078 protected Map<Object, Long> startLifeTime = null; 079 080 /** 081 * the start usage time for each object 082 */ 083 protected Map<Object, Long> startUsageTime = null; 084 085 /** 086 * number of existing instances 087 */ 088 protected int existingInstances = 0; 089 090 private int maxInstances = 50; 091 092 // min * sec * millisec. example: 15*60*1000 = 15 minutes 093 private int maxLifeTime = 15 * 60 * 1000; 094 095 // min * sec * millisec. example: 5*60*1000 = 5 minutes 096 private int maxUsageTime = 5 * 60 * 1000; 097 098 // milliseconds 099 private int updateInterval = 15000; 100 101 /** 102 * Creates a new ObjectPool object. 103 */ 104 protected ObjectPool() { 105 available = Collections.synchronizedList( new ArrayList<Object>( maxInstances ) ); 106 in_use = Collections.synchronizedList( new ArrayList<Object>( maxInstances ) ); 107 startLifeTime = Collections.synchronizedMap( new HashMap<Object, Long>( maxInstances ) ); 108 startUsageTime = Collections.synchronizedMap( new HashMap<Object, Long>( maxInstances ) ); 109 Timer timer = new Timer(); 110 timer.scheduleAtFixedRate( this, 10000, updateInterval ); 111 InputStream is = ObjectPool.class.getResourceAsStream( "pool.properties" ); 112 if ( is != null ) { 113 Properties props = new Properties(); 114 try { 115 props.load( is ); 116 is.close(); 117 } catch ( IOException e ) { 118 LOG.logInfo( "could not load pool properties" ); 119 return; 120 } 121 maxInstances = Integer.parseInt( props.getProperty( "maxInstances" ) ); 122 maxLifeTime = Integer.parseInt( props.getProperty( "maxLifeTime" ) ); 123 maxUsageTime = Integer.parseInt( props.getProperty( "maxUsageTime" ) ); 124 updateInterval = Integer.parseInt( props.getProperty( "updateInterval" ) ); 125 LOG.logInfo( "pool configuration read from pool.properties" ); 126 LOG.logDebug( "pool properties", this.toString() ); 127 } 128 } 129 130 /** 131 * dummy 132 * 133 * @return null 134 */ 135 public static ObjectPool getInstance() { 136 return null; 137 } 138 139 /** 140 * clears the complete pool. objects in used while the clear() method has been called won't be put back to the pool 141 * if released back through the <tt>releaseObject</tt> method. 142 */ 143 public synchronized void clear() { 144 in_use.clear(); 145 available.clear(); 146 startUsageTime.clear(); 147 startLifeTime.clear(); 148 } 149 150 /** 151 * release an object back to the pool so it is available for other requests. 152 * 153 * @param object 154 * @throws Exception 155 */ 156 public void releaseObject( Object object ) 157 throws Exception { 158 159 if ( in_use.contains( object ) ) { 160 // remove the object from the 'in use' container 161 in_use.remove( object ); 162 // remove the objects entry from the 'usage star time' container 163 startUsageTime.remove( object ); 164 // push the object to the list of available objects 165 available.add( object ); 166 } 167 } 168 169 /** 170 * this method will be called when the submitted object will be removed from the pool 171 * 172 * @param o 173 */ 174 public abstract void onObjectKill( Object o ); 175 176 /** 177 * @return the max life time 178 */ 179 public int getMaxLifeTime() { 180 return ( this.maxLifeTime ); 181 } 182 183 /** 184 * @param maxLifeTime 185 */ 186 public void setMaxLifeTime( int maxLifeTime ) { 187 this.maxLifeTime = maxLifeTime; 188 } 189 190 /** 191 * @return the max usage time 192 */ 193 public int getMaxUsageTime() { 194 return ( this.maxUsageTime ); 195 } 196 197 /** 198 * @param maxUsageTime 199 */ 200 public void setMaxUsageTime( int maxUsageTime ) { 201 this.maxUsageTime = maxUsageTime; 202 } 203 204 /** 205 * @return the update interval 206 */ 207 public int getUpdateInterval() { 208 return ( this.updateInterval ); 209 } 210 211 /** 212 * @param updateInterval 213 */ 214 public void setUpdateInterval( int updateInterval ) { 215 this.updateInterval = updateInterval; 216 } 217 218 /** 219 * @return max instances 220 */ 221 public int getMaxInstances() { 222 return ( this.maxInstances ); 223 } 224 225 /** 226 * @param maxInstances 227 */ 228 public void setMaxInstances( int maxInstances ) { 229 this.maxInstances = maxInstances; 230 } 231 232 @Override 233 public String toString() { 234 String ret = getClass().getName() + "\n"; 235 ret = "startLifeTime = " + startLifeTime + "\n"; 236 ret += ( "startUsageTime = " + startUsageTime + "\n" ); 237 ret += ( "maxLifeTime = " + maxLifeTime + "\n" ); 238 ret += ( "maxUsageTime = " + maxUsageTime + "\n" ); 239 ret += ( "updateInterval = " + updateInterval + "\n" ); 240 ret += ( "maxInstances = " + maxInstances + "\n" ); 241 return ret; 242 } 243 244 @Override 245 public void run() { 246 cleaner(); 247 usage(); 248 } 249 250 private synchronized void cleaner() { 251 252 try { 253 Object[] os = available.toArray(); 254 for ( int i = 0; i < os.length; i++ ) { 255 Object o = os[i]; 256 Long lng = startLifeTime.get( o ); 257 long l = System.currentTimeMillis(); 258 if ( lng == null || ( l - lng.longValue() ) > maxLifeTime ) { 259 if ( o != null ) { 260 available.remove( o ); 261 startLifeTime.remove( o ); 262 onObjectKill( o ); 263 } 264 existingInstances--; 265 } 266 } 267 268 } catch ( Exception e ) { 269 LOG.logError( "ObjectPool Cleaner ", e ); 270 } 271 272 } 273 274 private synchronized void usage() { 275 try { 276 Object[] os = in_use.toArray(); 277 for ( int i = 0; i < os.length; i++ ) { 278 Object o = os[i]; 279 Long lng = startUsageTime.get( o ); 280 long l = System.currentTimeMillis(); 281 if ( lng == null || ( l - lng.longValue() ) > maxUsageTime ) { 282 if ( o != null ) { 283 in_use.remove( o ); 284 startUsageTime.remove( o ); 285 startLifeTime.remove( o ); 286 onObjectKill( o ); 287 } 288 } 289 } 290 } catch ( Exception e ) { 291 LOG.logError( "UsageChecker ", e ); 292 } 293 294 } 295 296 }