Source Code Cross Referenced for JPool.java in  » J2EE » ow2-easybeans » org » ow2 » easybeans » pool » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » ow2 easybeans » org.ow2.easybeans.pool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * EasyBeans
003:         * Copyright (C) 2006 Bull S.A.S.
004:         * Contact: easybeans@ow2.org
005:         *
006:         * This library is free software; you can redistribute it and/or
007:         * modify it under the terms of the GNU Lesser General Public
008:         * License as published by the Free Software Foundation; either
009:         * version 2.1 of the License, or any later version.
010:         *
011:         * This library is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         * Lesser General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU Lesser General Public
017:         * License along with this library; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
019:         * USA
020:         *
021:         * --------------------------------------------------------------------------
022:         * $Id: JPool.java 1970 2007-10-16 11:49:25Z benoitf $
023:         * --------------------------------------------------------------------------
024:         */package org.ow2.easybeans.pool;
025:
026:        import java.util.ArrayList;
027:        import java.util.HashMap;
028:        import java.util.List;
029:        import java.util.Map;
030:
031:        import org.ow2.easybeans.api.pool.Pool;
032:        import org.ow2.easybeans.api.pool.PoolAttributes;
033:        import org.ow2.easybeans.api.pool.PoolException;
034:        import org.ow2.util.log.Log;
035:        import org.ow2.util.log.LogFactory;
036:
037:        /**
038:         * Abstract pool.<br>
039:         * Need to be extended to set-up the correct generic types used for BeanType and
040:         * Hint.<br>
041:         * @param <InstanceType> the type of the object that are managed by the pool
042:         *        (could be EasyBeansSLSB, etc.)
043:         * @param <Clue> a clue to retrieve a specific instance in the pool
044:         * @author Florent Benoit
045:         */
046:        public class JPool<InstanceType, Clue> implements 
047:                Pool<InstanceType, Clue>, PoolAttributes {
048:
049:            /**
050:             * Default timeout (10s) in ms.
051:             */
052:            private static final long DEFAULT_TIMEOUT = 10000;
053:
054:            /**
055:             * Default maximum of waiters (1000).
056:             */
057:            private static final int DEFAULT_MAX_WAITERS = 1000;
058:
059:            /**
060:             * High Value for no limit for the connection pool.
061:             */
062:            private static final int NO_LIMIT = -1;
063:
064:            /**
065:             * Logger used.
066:             */
067:            private Log logger = LogFactory.getLog(JPool.class);
068:
069:            /**
070:             * Factory used for delegate creating, matching, removing actions.
071:             */
072:            private PoolFactory<InstanceType, Clue> poolFactory = null;
073:
074:            /**
075:             * List of available objects in the pool.
076:             */
077:            private List<InstanceType> availableList = null;
078:
079:            /**
080:             * List of objects which are currently busy and not available from the pool.
081:             */
082:            private List<InstanceType> busyList = null;
083:
084:            /**
085:             * Information on entries managed in the pool.
086:             */
087:            private Map<InstanceType, PoolEntryStatistics> infoMap = null;
088:
089:            /**
090:             * Minimum size of the pool.
091:             */
092:            private int minSize = 0;
093:
094:            /**
095:             * Maximum size of the pool.
096:             */
097:            private int maxSize = NO_LIMIT;
098:
099:            /**
100:             * Initial size of the pool.
101:             */
102:            private int initSize = 0;
103:
104:            /**
105:             * Maximum size of the pool is strict.
106:             */
107:            private boolean strict = true;
108:
109:            /**
110:             * Max nb of waiters allowed to wait for an instance.
111:             */
112:            private int maxWaiters = DEFAULT_MAX_WAITERS;
113:
114:            /**
115:             * Max nb of milliseconds to wait for an object when the pool is full.
116:             */
117:            private long waiterTimeout = DEFAULT_TIMEOUT;
118:
119:            /**
120:             * Current number of waiters.
121:             */
122:            private int currentWaiters = 0;
123:
124:            /**
125:             * Maximum number of waiters during current period.
126:             */
127:            private int highMaxWaiters = 0;
128:
129:            /**
130:             * Total nb of waiters since pool creation.
131:             */
132:            private int totalWaiters = 0;
133:
134:            /**
135:             * total waiting time in milliseconds.
136:             */
137:            private long totalWaitingTime = 0;
138:
139:            /**
140:             * Maximum waiting time during current period.
141:             */
142:            private long highWaitingTime = 0;
143:
144:            /**
145:             * Total number of instances since the pool creation.
146:             */
147:            private int servedInstance = 0;
148:
149:            /**
150:             * Total nb of instance not served due to timeout.
151:             */
152:            private int rejectedTimeout = 0;
153:
154:            /**
155:             * Total nb of instance not served due to an overflow of waiters.
156:             */
157:            private int rejectedFull = 0;
158:
159:            /**
160:             * Allow to build instance with the same clue if the pool is not at the max size.
161:             * For example, for stateful this is not allowed.
162:             */
163:            private boolean allowSharedInstance = true;
164:
165:            /**
166:             * Builds a new pool.
167:             * @param poolFactory factory used for delegating create, remove, etc.
168:             */
169:            public JPool(final PoolFactory<InstanceType, Clue> poolFactory) {
170:
171:                // factory use to delegate some operations
172:                this .poolFactory = poolFactory;
173:
174:                // available entries
175:                this .availableList = new ArrayList<InstanceType>();
176:
177:                // entries send to client, which are busy
178:                this .busyList = new ArrayList<InstanceType>();
179:
180:                // statistics on entries
181:                infoMap = new HashMap<InstanceType, PoolEntryStatistics>();
182:            }
183:
184:            /**
185:             * Gets an object from the pool.
186:             * @return an instance of an object with type Type.
187:             * @throws PoolException if instance cannot be returned.
188:             */
189:            public InstanceType get() throws PoolException {
190:                // delegates to getter method with a parameter
191:                return this .get(null);
192:            }
193:
194:            /**
195:             * Gets an object by using a specific hint.
196:             * @param clue attribute used to retrieve a given instance
197:             * @return a specific instance of the resource.
198:             * @throws PoolException if instance cannot be returned.
199:             */
200:            public synchronized InstanceType get(final Clue clue)
201:                    throws PoolException {
202:                InstanceType instance = null;
203:
204:                // time to wait when pool is full
205:                long timeToWait = waiterTimeout;
206:
207:                // Try to find an instance
208:                // Enter in the big loop :)
209:                while (instance == null) {
210:
211:                    // instances are available
212:                    if (!availableList.isEmpty()) {
213:                        logger.debug("Instances are available");
214:
215:                        int indexToExtract = -1;
216:
217:                        // No clue, get first instance available
218:                        if (clue == null) {
219:                            logger
220:                                    .debug("No clue, return the first available entry.");
221:                            indexToExtract = 0;
222:                        } else {
223:                            logger
224:                                    .debug("Clue is used, try to get a matching entry.");
225:                            // need to find a matching instance.
226:                            // use this kind of loop to call remove() method
227:                            // with an index instead of an element.
228:                            for (int i = 0; i < availableList.size(); i++) {
229:                                InstanceType tmpInstance = availableList.get(i);
230:                                if (poolFactory.isMatching(tmpInstance, clue)) {
231:                                    logger
232:                                            .debug(
233:                                                    "Found a matching instance, instance = {0}",
234:                                                    tmpInstance);
235:                                    indexToExtract = i;
236:                                    break;
237:                                }
238:                            }
239:                            // Note : instance could not be found
240:                        }
241:                        // An instance is available ?
242:                        if (indexToExtract != -1) {
243:                            logger
244:                                    .debug(
245:                                            "Remove from available instance, item with index {0}",
246:                                            Integer.valueOf(indexToExtract));
247:                            instance = availableList.remove(indexToExtract);
248:                            busyList.add(instance);
249:                        }
250:                    }
251:
252:                    /**
253:                     * If here :
254:                     * <ul>
255:                     * <li> - No objects available in the pool</li>
256:                     * <li>or - No matching instance in the pool</li>
257:                     * </ul>
258:                     */
259:                    if (instance == null) {
260:                        // current size of managed entries (available and busy)
261:                        int curSize = availableList.size() + busyList.size();
262:
263:                        boolean sharedInstance = true;
264:                        if (!allowSharedInstance) {
265:                            // Search if an instance is currently used
266:                            for (int i = 0; i < busyList.size(); i++) {
267:                                InstanceType tmpInstance = busyList.get(i);
268:                                if (poolFactory.isMatching(tmpInstance, clue)) {
269:                                    logger
270:                                            .debug(
271:                                                    "Found a matching instance, instance = {0}",
272:                                                    tmpInstance);
273:                                    sharedInstance = false;
274:                                    break;
275:                                }
276:                            }
277:                        }
278:
279:                        // limit not reached (or pool without limit)
280:                        if (sharedInstance
281:                                && (maxSize == NO_LIMIT || curSize < maxSize)) {
282:                            logger
283:                                    .debug(
284:                                            "Maximum size not reached, can create a new entry with clue = {0}",
285:                                            clue);
286:                            instance = poolFactory.create(clue);
287:                            busyList.add(instance);
288:                        } else if (sharedInstance && availableList.size() > 0) {
289:                            // limit reached but pool entries still available
290:                            logger
291:                                    .debug("limit reached but entries available in the pool. Replace one by a new one.");
292:
293:                            // get first entry found (that will be replaced)
294:                            InstanceType previousInstance = availableList
295:                                    .get(0);
296:
297:                            // remove it from the delegating factory.
298:                            // Factory is notified that the instance is being removed.
299:                            poolFactory.remove(previousInstance);
300:
301:                            // now, remove the entry from pool
302:                            availableList.remove(previousInstance);
303:                            // and from statistics
304:                            infoMap.remove(previousInstance);
305:
306:                            // As previous instance has been removed, new one can be
307:                            // created
308:                            instance = poolFactory.create(clue);
309:                            // this instance is now busy.
310:                            busyList.add(instance);
311:                        } else {
312:                            logger
313:                                    .debug("limit reached and no available instances in the pool");
314:                            boolean timeoutWokenUp = true;
315:                            long startSleeping = 0;
316:
317:                            // Need to wait
318:                            if (timeToWait > 0) {
319:                                if (currentWaiters < maxWaiters) {
320:                                    currentWaiters++;
321:                                    // Store the maximum concurrent waiters
322:                                    if (highMaxWaiters < currentWaiters) {
323:                                        highMaxWaiters = currentWaiters;
324:                                    }
325:                                    if (startSleeping == 0) {
326:                                        startSleeping = System
327:                                                .currentTimeMillis();
328:                                        logger.debug("Waiting an instance");
329:                                    }
330:                                    try {
331:                                        wait(timeToWait);
332:                                    } catch (InterruptedException ie) {
333:                                        logger.warn(
334:                                                "Waiter has been interrupted",
335:                                                ie);
336:                                    } finally {
337:                                        currentWaiters--;
338:                                    }
339:                                    long sleepTime = System.currentTimeMillis()
340:                                            - startSleeping;
341:                                    // check if waiter has been woken up
342:                                    timeoutWokenUp = (waiterTimeout - sleepTime <= 0);
343:
344:                                    // increment counters
345:                                    totalWaiters++;
346:                                    totalWaitingTime += sleepTime;
347:                                    if (highWaitingTime < sleepTime) {
348:                                        highWaitingTime = sleepTime;
349:                                    }
350:                                    // continue if we were only notified. (no timeout)
351:                                    if (!timeoutWokenUp) {
352:                                        continue;
353:                                    }
354:                                }
355:                            }
356:
357:                            // timeout expired and no entry is available
358:                            if (timeoutWokenUp && availableList.isEmpty()
359:                                    && busyList.size() >= maxSize) {
360:                                if (startSleeping > 0) {
361:                                    rejectedTimeout++;
362:                                    logger
363:                                            .warn("Cannot create an instance due to a timeout");
364:                                } else {
365:                                    rejectedFull++;
366:                                    logger.warn("Cannot create an instance");
367:                                }
368:                                throw new PoolException(
369:                                        "No more instances available");
370:                            }
371:                        }
372:                    }
373:                }
374:
375:                // TODO: delegate to factory the entry
376:                PoolEntryStatistics poolEntryStat = new PoolEntryStatistics();
377:
378:                infoMap.put(instance, poolEntryStat);
379:
380:                // printLists();
381:
382:                // recomputeBusy();
383:
384:                servedInstance++;
385:                return instance;
386:            }
387:
388:            /**
389:             * Puts back the instance in the pool so it can be reused.
390:             * @param instance which will be put back in the pool.
391:             * @throws PoolException if instance is not released.
392:             */
393:            public synchronized void release(final InstanceType instance)
394:                    throws PoolException {
395:
396:                if (!busyList.contains(instance)) {
397:                    logger
398:                            .debug(
399:                                    "Attempt to release inactive resource {0}. Probably discarded.",
400:                                    instance);
401:                    return;
402:                }
403:                busyList.remove(instance);
404:                logger.debug("Put back into the pool the instance {0}",
405:                        instance);
406:
407:                availableList.add(instance);
408:                infoMap.remove(instance);
409:
410:                // Notify 1 thread waiting for that an instance is available.
411:                if (currentWaiters > 0) {
412:                    notify();
413:                }
414:            }
415:
416:            /**
417:             * Discard the instance which is in the pool.
418:             * @param instance which will be discarded.
419:             * @throws PoolException if instance is not discarded
420:             */
421:            public synchronized void discard(final InstanceType instance)
422:                    throws PoolException {
423:                if (!busyList.contains(instance)) {
424:                    throw new PoolException(
425:                            "Attempt to discard an inactive resource("
426:                                    + instance + ")");
427:                }
428:
429:                // Notify the factory that it's going to be removed
430:                poolFactory.remove(instance);
431:
432:                // Remove instance from the busy & info list
433:                busyList.remove(instance);
434:                infoMap.remove(instance);
435:
436:                // Notify 1 thread waiting that an instance has been freed
437:                if (currentWaiters > 0) {
438:                    notify();
439:                }
440:
441:            }
442:
443:            /**
444:             * Allow to share instances (shouldn't be use in stateful case as one
445:             * stateful ID is linked to one client. No Stateful with same ID are
446:             * authorized).
447:             * @param allowSharedInstance true if it is allowed, else false.
448:             */
449:            public void setAllowSharedInstance(final boolean allowSharedInstance) {
450:                this .allowSharedInstance = allowSharedInstance;
451:            }
452:
453:            /**
454:             * Return true if many instances of the same object can be created (when pool is not full).
455:             * @return true if this is allowed.
456:             */
457:            public boolean isAllowSharedInstance() {
458:                return allowSharedInstance;
459:            }
460:
461:            /**
462:             * Start the pool.<br>
463:             * It could create initial instances if specified.
464:             * @throws PoolException if initialization fails
465:             */
466:            public void start() throws PoolException {
467:
468:            }
469:
470:            /**
471:             * Stop this pool.
472:             * @throws PoolException if destroy fails
473:             */
474:            public void stop() throws PoolException {
475:
476:            }
477:
478:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.