Source Code Cross Referenced for GenericPool.java in  » Database-JDBC-Connection-Pool » xapool » org » enhydra » jdbc » 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 » Database JDBC Connection Pool » xapool » org.enhydra.jdbc.pool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * XAPool: Open Source XA JDBC Pool
003:         * Copyright (C) 2003 Objectweb.org
004:         * Initial Developer: Lutris Technologies Inc.
005:         * Contact: xapool-public@lists.debian-sf.objectweb.org
006:         *
007:         * This library is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU Lesser General Public
009:         * License as published by the Free Software Foundation; either
010:         * version 2.1 of the License, or any later version.
011:         *
012:         * This library is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this library; if not, write to the Free Software
019:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
020:         * USA
021:         */
022:        package org.enhydra.jdbc.pool;
023:
024:        import java.util.Hashtable;
025:        import java.util.Enumeration;
026:        import java.util.Vector;
027:
028:        import org.enhydra.jdbc.core.JdbcThreadFactory;
029:        import org.enhydra.jdbc.util.Logger;
030:
031:        /**
032:         * GenericPool is the main class of the Pool. It works with any kind of object
033:         * that's implement PoolHelper (must provide specific operation on the specific
034:         * object) Objects stored in hashtables are GenerationObject object. These
035:         * objects allow to store multiples things in them, in particular, the
036:         * generation number to identify the generation of an object.
037:         */
038:        public class GenericPool {
039:            private long lifeTime; // lifetime of an object in the pool
040:
041:            private Hashtable locked, unlocked;
042:
043:            // two hashtables, to stock objects in use and free objects
044:            private Vector hitList; // holds expired objects until they are killed.
045:
046:            private JdbcThreadFactory threadFactory; // thread factory
047:
048:            private int minSize; // minimum size of the pool, set to 0
049:
050:            private int maxSize; // maximum size of the pool, if set to 0 : unlimited
051:
052:            private PoolHelper poolHelper; // object type
053:
054:            private int count; // count the number of object in the pool
055:
056:            private boolean gc; // gc system call
057:
058:            private boolean debug; // debug flag
059:
060:            private long deadLockMaxWait;
061:
062:            // time to wait before deadlock (return exception)
063:            private long deadLockRetryWait; // time to wait before 2 try of loop
064:
065:            private Logger log;
066:
067:            /**
068:             * checking level object 0 = no special checking 1 = just a check on an
069:             * object 2 = test the object 3 = just a check on an object (for all the
070:             * objects) 4 = test the object (for all the objects)
071:             */
072:            private int checkLevelObject = 1;
073:
074:            protected Thread keeper; // thread to clean up dead objects
075:
076:            protected PoolKeeper poolKeeper;
077:
078:            private long sleepTime; // sleeptime for the pool keeper
079:
080:            /**
081:             * Generation number. When an error occurs, all objects of the same
082:             * generation or earlier are dropped.
083:             */
084:            protected int generation = 1;
085:
086:            // Total lifetime the object can exist
087:            private long maxLifeTime;
088:
089:            // Default Total time the object can be exist.
090:            // Default = 0 : can live forever.
091:            public static final long DEFAULT_MAXLIFETIME = 0;
092:
093:            // Default values
094:            public static final long DEFAULT_EXPIRATION = 600000; // 10 minutes
095:
096:            // public static final long DEFAULT_EXPIRATION = 30000; // 30 secondes
097:            public static final long DEFAULT_SLEEPTIME = 300000; // 5 minutes
098:
099:            public static final int DEFAULT_MINSIZE = 2; // 2 objects
100:
101:            public static final int DEFAULT_MAXSIZE = 50; // 50 objects
102:
103:            public static final int DEFAULT_DEADLOCKMAXWAIT = 300000; // 5 minutes
104:
105:            public static final int DEFAULT_DEADLOCKRETRYWAIT = 10000; // 10 seconds
106:
107:            /**
108:             * Creates an GenericPool with the default params.
109:             */
110:            public GenericPool(PoolHelper helper) {
111:                this (helper, DEFAULT_MINSIZE, DEFAULT_MAXSIZE,
112:                        DEFAULT_EXPIRATION, DEFAULT_SLEEPTIME,
113:                        DEFAULT_MAXLIFETIME);
114:            }
115:
116:            public GenericPool(PoolHelper helper, int initSize) {
117:                this (helper, DEFAULT_MINSIZE, initSize, DEFAULT_EXPIRATION,
118:                        DEFAULT_SLEEPTIME, DEFAULT_MAXLIFETIME);
119:            }
120:
121:            /**
122:             * Constructor, set the two hashtables and set by default the other values
123:             */
124:            public GenericPool(PoolHelper helper, int minSize, int maxSize,
125:                    long lifeTime, long sleepTime, long maxLifeTime) {
126:                this .threadFactory = null;
127:                this .lifeTime = lifeTime;
128:                this .maxLifeTime = maxLifeTime;
129:                this .minSize = minSize;
130:                this .maxSize = maxSize;
131:                this .poolHelper = helper;
132:                // helper is the type of the object (interface)
133:                this .sleepTime = sleepTime;
134:                this .checkLevelObject = 0;
135:                this .deadLockMaxWait = DEFAULT_DEADLOCKMAXWAIT;
136:                this .deadLockRetryWait = DEFAULT_DEADLOCKRETRYWAIT;
137:            }
138:
139:            /**
140:             * Start method, to initialize independant values of the pool
141:             */
142:            public synchronized void start() {
143:                locked = new Hashtable(); // create locked objects pool
144:                unlocked = new Hashtable(); // create unlocked objects pool
145:                hitList = new Vector();
146:                count = 0; // 0 element to start
147:                gc = false; // do not actions concerning garbage collector
148:                long now = System.currentTimeMillis(); // current time
149:
150:                // to obtain to the beginning minSize objects in the pool
151:                for (int i = 0; i < minSize; i++) { // count have to be equal to minSize
152:                    try {
153:                        GenerationObject genObject = poolHelper.create();
154:                        unlocked.put(genObject, new Long(now));
155:                        // put it in the unlocked pool
156:                    } catch (Exception e) {
157:                        log.error("Error Exception in GenericPool:start " + e);
158:                    }
159:                    ++count; // there is one more element in the pool
160:                }
161:
162:                // keeper removes dead or useless objects
163:                if (threadFactory != null) {
164:                    try {
165:                        this .poolKeeper = new PoolKeeper(sleepTime, this );
166:                        this .keeper = threadFactory.getThread(poolKeeper);
167:                    } catch (Exception e) {
168:                        throw new IllegalStateException(e.getMessage());
169:                    }
170:                } else {
171:                    // keep a handle to the poolkeeper so we can destroy it later
172:                    this .poolKeeper = new PoolKeeper(sleepTime, this );
173:                    this .keeper = new Thread(poolKeeper);
174:
175:                }
176:                keeper.start();
177:                // start the thread to verify element in the pool(unlocked)
178:                log.debug("GenericPool:start pool started");
179:            }
180:
181:            /*
182:             * Returns object from the pool or creates a connection outside
183:             * synchronization to prevent hanging.
184:             */
185:            private Object getFromPool(String user, String password)
186:                    throws Exception {
187:
188:                long now = System.currentTimeMillis(); // current time to compare
189:                if (getUnlockedObjectCount() > 0) {
190:                    // now, we have to return an object to the user
191:                    GenerationObject o = null;
192:                    Object realObject = null;
193:                    Long life = null;
194:
195:                    Enumeration e = unlocked.keys(); // then take them
196:                    while (e.hasMoreElements()) { // for each objects ...
197:                        synchronized (this ) {
198:
199:                            // Ensure that there are object in the unlocked
200:                            // collection
201:                            if (getUnlockedObjectCount() == 0)
202:                                break;
203:
204:                            o = (GenerationObject) e.nextElement();
205:                            life = (Long) unlocked.get(o);
206:                            if (life == null) {
207:                                // Fix for #303462; note that this fixes the problem, but Enumeration's on Hashtable's
208:                                // are by definition somewhat unpredictable; a more robust fix may be in order
209:                                log
210:                                        .debug("GenericPool:getFromPool fix for #303462 encountered");
211:                                continue;
212:                            }
213:
214:                            unlocked.remove(o);
215:                            // In any case the object will be removed.
216:                            // Prevents others accessing the object while we are
217:                            // not synchronized.
218:                            realObject = o.getObj();
219:                        }
220:
221:                        // Verify that the life object is valid
222:                        if (life == null)
223:                            break;
224:
225:                        // first, verify if the object is not dead (lifetime)
226:                        if (life == null
227:                                || (now - life.longValue()) > lifeTime
228:                                || (maxLifeTime > 0 && (now - o.getCreated()) > maxLifeTime)) {
229:
230:                            // object has expired
231:                            log
232:                                    .debug("GenericPool:getFromPool an object has expired");
233:                            removeUnlockedObject(o);
234:                        } else {
235:                            log
236:                                    .debug("GenericPool:getFromPool check the owner of the connection");
237:                            if (checkOwner(o, user, password)) {
238:                                log
239:                                        .debug("GenericPool:getFromPool owner is verified");
240:                                // second, verification of the object if needed
241:                                if ((checkLevelObject == 0)
242:                                        || ((checkLevelObject == 1) && poolHelper
243:                                                .checkThisObject(realObject))
244:                                        || ((checkLevelObject == 2) && poolHelper
245:                                                .testThisObject(realObject))) {
246:
247:                                    locked.put(o, new Long(now));
248:                                    // put it in the locked pool
249:                                    log
250:                                            .debug("GenericPool:getFromPool return an object (after verification if needed)");
251:                                    return (o.getObj()); // return this element
252:                                } else { // object failed validation
253:                                    //			System.out.println("removeUnlockedObject="+realObject);
254:                                    log
255:                                            .debug("GenericPool:getFromPool kill an object from the pool");
256:                                    removeUnlockedObject(o);
257:                                }
258:
259:                            } else
260:                                log
261:                                        .debug("GenericPool:getFromPool owner is FALSE");
262:                        }
263:                    }
264:                } // if getUnlockedObjectCount() > 0
265:
266:                // if no objects available, create a new one
267:                boolean create = false;
268:                synchronized (this ) {
269:                    if (count < maxSize) {
270:                        create = true;
271:                        count++; // assume we can create a connection.
272:                    }
273:                }
274:                if (create) {
275:                    //			System.out.println("on doit creer une connection");
276:                    // if number of pooled object is < max size of the pool
277:                    log
278:                            .debug("GenericPool:getFromPool no objects available, create a new one");
279:                    try {
280:                        //			System.out.println("on doit creer une connection CREATE");
281:                        GenerationObject genObject = poolHelper.create(user,
282:                                password);
283:                        //			System.out.println("nouvel objet="+genObject.getObj());
284:                        //			System.out.println("on doit creer une connection PUT");
285:                        locked.put(genObject, new Long(now));
286:                        // put it in the locked pool
287:                        return (genObject.getObj()); // and return this element
288:                    } catch (Exception excp) {
289:                        synchronized (this ) {
290:                            count--; // our assumption failed. rollback.
291:                        }
292:
293:                        log
294:                                .error("GenericPool:getFromPool Error Exception in GenericPool:getFromPool");
295:                        // cney: rethrow exception thrown by create
296:                        throw excp;
297:                    }
298:                }
299:
300:                return null;
301:            }
302:
303:            public synchronized boolean checkOwner(GenerationObject genObject,
304:                    String user, String password) {
305:                return equals(user, genObject.getUser())
306:                        && equals(password, genObject.getPassword());
307:            }
308:
309:            JdbcThreadFactory getThreadFactory() {
310:                return threadFactory;
311:            }
312:
313:            void setThreadFactory(JdbcThreadFactory tf) {
314:                threadFactory = tf;
315:            }
316:
317:            private boolean equals(String a, String b) {
318:                if (a == null)
319:                    return (b == null);
320:                if (b == null)
321:                    return (a == null);
322:                return a.equals(b);
323:            }
324:
325:            /**
326:             * return pooled object
327:             */
328:            public Object checkOut(String user, String password)
329:                    throws Exception {
330:                log.debug("GenericPool:checkOut an object");
331:                long now = System.currentTimeMillis(); // current time to compare
332:                GenerationObject o;
333:                Enumeration e;
334:                Object realObject;
335:                log.debug("GenericPool:checkOut UnlockedObjectCount="
336:                        + getUnlockedObjectCount());
337:                log.debug("GenericPool:checkOut LockedObjectCount="
338:                        + getLockedObjectCount());
339:                log.debug("GenericPool:checkOut count=" + count + " maxSize="
340:                        + maxSize);
341:
342:                if (getUnlockedObjectCount() > 0) {
343:                    // if there are objects in the unlocked pool
344:                    if ((checkLevelObject == 3) || (checkLevelObject == 4)) { // need
345:                        // to
346:                        // verify
347:                        // all
348:                        // the
349:                        // objects
350:
351:                        e = unlocked.keys();
352:                        while (e.hasMoreElements()) {
353:                            o = (GenerationObject) e.nextElement();
354:                            realObject = o.getObj(); // take the current object
355:                            // first, verify if the object is not dead (lifetime)
356:                            Long life = (Long) unlocked.get(o);
357:                            if (life == null
358:                                    || (now - life.longValue()) > lifeTime
359:                                    || (maxLifeTime > 0 && (now - o
360:                                            .getCreated()) > maxLifeTime)) {
361:
362:                                // object has expired
363:                                log
364:                                        .debug("GenericPool:checkOut an object has expired");
365:                                removeUnlockedObject(o);
366:                                // minimumObject(user, password);
367:                                // build object in the pool if it is lesser than minSize
368:                            } else {
369:                                log
370:                                        .debug("GenericPool:checkOut check the owner of the connection");
371:                                if (checkOwner(o, user, password)) {
372:                                    if (((checkLevelObject == 3) && !poolHelper
373:                                            .checkThisObject(realObject))
374:                                            || ((checkLevelObject == 4) && !poolHelper
375:                                                    .testThisObject(realObject))) {
376:                                        log
377:                                                .debug("GenericPool:checkOut remove object checkLevelObject="
378:                                                        + checkLevelObject);
379:                                        removeUnlockedObject(o);
380:                                        // minimumObject(user, password);
381:                                        // build object in the pool if it is lesser than
382:                                        // minSize
383:                                    }
384:                                }
385:                            }
386:                        }
387:                    }
388:
389:                }
390:
391:                int currentWait = 0;
392:
393:                Object obj = getFromPool(user, password);
394:                while ((obj == null) && (currentWait < getDeadLockMaxWait())) {
395:                    log.info("GenericPool:checkOut waiting for an object :"
396:                            + this .poolHelper.toString());
397:                    try {
398:                        synchronized (this ) {
399:                            wait(getDeadLockRetryWait());
400:                        }
401:                    } catch (InterruptedException excp) {
402:                        log
403:                                .error("GenericPool:checkOut ERROR Failed while waiting for an object: "
404:                                        + excp);
405:                    }
406:                    currentWait += getDeadLockRetryWait();
407:                    obj = getFromPool(user, password);
408:                }
409:
410:                if (obj == null)
411:                    throw new Exception(
412:                            "GenericPool:checkOut ERROR  impossible to obtain a new object from the pool");
413:
414:                return obj;
415:            }
416:
417:            synchronized public void minimumObject() {
418:                minimumObject(null, null);
419:            }
420:
421:            synchronized public void minimumObject(String user, String password) {
422:                log
423:                        .debug("GenericPool:minimumObject create object if there are less than minSize objects in the pool count ="
424:                                + count);
425:                if ((count < minSize) && (unlocked != null)) { // if pool has less than
426:                    // minSize elements
427:                    long now = System.currentTimeMillis(); // current time
428:
429:                    for (int i = count; i < minSize; i++) { // count have to be equal to
430:                        // minSize
431:                        try {
432:                            GenerationObject genObject;
433:                            if ((user != null) && (password != null))
434:                                genObject = poolHelper.create();
435:                            else
436:                                genObject = poolHelper.create(user, password);
437:                            unlocked.put(genObject, new Long(now));
438:                            // put it in the unlocked pool
439:                        } catch (Exception e) {
440:                            log
441:                                    .error("GenericPool:minimumObject Error Exception in GenericPool:minimumObject");
442:                        }
443:                    }
444:                    log.debug("GenericPool:minimumObject count=" + count
445:                            + " Unlocked=" + this .getUnlockedObjectCount()
446:                            + " locked=" + this .getLockedObjectCount());
447:
448:                    count = minSize; // pool has now minSize element
449:                }
450:            }
451:
452:            /**
453:             * remove object from locked pool
454:             */
455:            public synchronized void checkIn(Object o) {
456:                log.debug("GenericPool:checkIn return an object to the pool");
457:
458:                for (Enumeration enumeration = locked.keys(); enumeration
459:                        .hasMoreElements();) { // for
460:                    // each
461:                    // object
462:                    // of
463:                    GenerationObject obj = (GenerationObject) enumeration
464:                            .nextElement();
465:                    // the locked pool
466:
467:                    if (obj.getObj().equals(o)) {
468:                        locked.remove(obj); // remove the object from the locked pool
469:                        unlocked.put(obj, new Long(System.currentTimeMillis()));
470:
471:                        // we have to verify if the generation of the object is still
472:                        // valid
473:                        int genObj = obj.getGeneration(); // get the generation number
474:
475:                        // if the generation number of the object is not valid, test the
476:                        // object
477:                        if (generation > genObj) {
478:                            if (!poolHelper.checkThisObject(obj.getObj()))
479:                                // if the object is not valid
480:                                removeUnlockedObject(obj);
481:
482:                        }
483:                        notifyAll();
484:                    }
485:                }
486:
487:                if (count > maxSize) {
488:                    // if we have more than maxSize object in the pool
489:                    log
490:                            .info("GenericPool:checkIn more than maxSize object in the pool");
491:                    Enumeration enumeration = unlocked.keys(); // get the unlocked pool
492:                    for (int i = maxSize; i < count; i++) { // try to remove object from
493:                        // this pool
494:                        if (getUnlockedObjectCount() > 0) {
495:                            GenerationObject obj = (GenerationObject) enumeration
496:                                    .nextElement();
497:                            removeUnlockedObject(obj);
498:                        }
499:                    }
500:                    // now, the size of the pool is changed
501:                    // NOTE : count number ca be greater than maxSize here, in case of
502:                    // there is no
503:                    // available object to delete in the unlocked pool
504:                    count = getUnlockedObjectCount() + getLockedObjectCount();
505:                    if (count > maxSize)
506:                        log
507:                                .warn("GenericPool:checkIn Be careful, the maximum size of the pool does not correspond"
508:                                        + " to your data. When objects will be check in, the pool "
509:                                        + "will decrease");
510:                }
511:
512:            }
513:
514:            synchronized public void removeUnlockedObject(GenerationObject obj) {
515:                --count;
516:                notifyAll(); // there is room for new connections.
517:                unlocked.remove(obj);
518:                hitList.add(obj); // killing is done by the keeper thread.
519:            }
520:
521:            public void setDebug(boolean debug) {
522:                this .debug = debug;
523:            }
524:
525:            public boolean isDebug() {
526:                return debug;
527:            }
528:
529:            public synchronized void setMinSize(int min) throws Exception {
530:                if (min < 0)
531:                    throw new Exception(
532:                            "GenericPool:setMinSize Minimum size of the pool can't be lesser than 0");
533:                else if (min > maxSize)
534:                    throw new Exception(
535:                            "GenericPool:setMinSize Minimum size of the pool can't be greater than the maxSize ("
536:                                    + maxSize + ")");
537:                else {
538:                    this .minSize = min;
539:                    // minimumObject(); // build object in the pool if it is lesser than
540:                    // minSize
541:                }
542:
543:            }
544:
545:            public synchronized void setMaxSize(int max) throws Exception {
546:                if (max < 0)
547:                    throw new Exception(
548:                            "GenericPool:setMaxSize Maximum size of the pool can't be lesser than 0");
549:                else if (max < minSize)
550:                    throw new Exception(
551:                            "GenericPool:setMaxSize Maximum size of the pool can't be lesser than the minSize ("
552:                                    + minSize + ")");
553:                else {
554:                    this .maxSize = max;
555:                    if (count > max) { // if pool has more than max element
556:                        log
557:                                .info("GenericPool:setMaxSize pool has more than max element");
558:                        // we try to remove element from the unlocked pool
559:                        Enumeration enumeration = unlocked.keys();
560:                        for (int i = max; i < count; i++) {
561:                            if (getUnlockedObjectCount() > 0) {
562:                                // if there is element in the unlocked pool
563:                                GenerationObject o = (GenerationObject) enumeration
564:                                        .nextElement();
565:                                removeUnlockedObject(o);
566:                            }
567:                        }
568:
569:                        // new size is :
570:                        count = getUnlockedObjectCount()
571:                                + getLockedObjectCount();
572:                        // if there is still more than max element, the objects will be
573:                        // removed
574:                        // when the check in operation will be performed.
575:                        if (count > max)
576:                            log
577:                                    .warn("GenericPool:setMaxSize Be careful, the maximum size of "
578:                                            + "the pool does not correspond to your data. When objects "
579:                                            + "will be check in, the pool will decrease");
580:                    }
581:                }
582:            }
583:
584:            public void setLifeTime(long lifeTime) {
585:                this .lifeTime = lifeTime;
586:            }
587:
588:            public void setSleepTime(long sleepTime) {
589:                this .sleepTime = sleepTime;
590:            }
591:
592:            public void setGeneration(int generation) {
593:                this .generation = generation;
594:                log
595:                        .debug("GenericPool:setGeneration Be careful, it is very dangerous to change "
596:                                + "the generation number, many objects could be destroyed");
597:            }
598:
599:            public void setGC(boolean gc) {
600:                this .gc = gc;
601:            }
602:
603:            /**
604:             * level are accepted between 0 and 4
605:             */
606:            public void setCheckLevelObject(int level) {
607:                if ((level > 0) && (level <= 4))
608:                    this .checkLevelObject = level;
609:            }
610:
611:            public void setDeadLockMaxWait(long deadLock) {
612:                this .deadLockMaxWait = deadLock;
613:            }
614:
615:            public void setDeadLockRetryWait(long deadLockRetryWait) {
616:                this .deadLockRetryWait = deadLockRetryWait;
617:            }
618:
619:            public int getMinSize() {
620:                return minSize;
621:            }
622:
623:            public int getMaxSize() {
624:                return maxSize;
625:            }
626:
627:            public long getLifeTime() {
628:                return lifeTime;
629:            }
630:
631:            public boolean isGC() {
632:                return gc;
633:            }
634:
635:            public int getCount() {
636:                return count;
637:            }
638:
639:            public long getSleepTime() {
640:                return sleepTime;
641:            }
642:
643:            public int getGeneration() {
644:                return generation;
645:            }
646:
647:            public int getCheckLevelObject() {
648:                return checkLevelObject;
649:            }
650:
651:            /**
652:             * switch off the pool
653:             */
654:            public void stop() {
655:                log.debug("GenericPool:stop start to stop the pool");
656:                if ((getLockedObjectCount() != 0)
657:                        || (getUnlockedObjectCount() != 0)) {
658:                    expireAll(); // try to kill all the objects in the 2 pools
659:                    if (poolKeeper != null)
660:                        poolKeeper.stop(); // release the pool.
661:                    keeper.interrupt(); // and interrupt the pool keeper
662:                    locked.clear(); // clear the locked pool
663:                    unlocked.clear(); // clear the unlocked pool
664:                    locked = null;
665:                    unlocked = null;
666:                    count = 0; // there is no element in the pool
667:                }
668:                log.debug("GenericPool:stop pool stopped");
669:            }
670:
671:            /**
672:             * returns the current number of objects that are locked
673:             */
674:            public int getLockedObjectCount() {
675:                if (locked != null)
676:                    return locked.size();
677:                else
678:                    return 0;
679:            }
680:
681:            /**
682:             * returns the current number of objects that are unlocked
683:             */
684:            public int getUnlockedObjectCount() {
685:                if (unlocked != null)
686:                    return unlocked.size();
687:                else
688:                    return 0;
689:            }
690:
691:            public long getDeadLockMaxWait() {
692:                return this .deadLockMaxWait;
693:            }
694:
695:            public long getDeadLockRetryWait() {
696:                return this .deadLockRetryWait;
697:            }
698:
699:            /**
700:             * returns information from the pool
701:             */
702:            public String toString() {
703:                StringBuffer sb = new StringBuffer();
704:                sb.append("GenericPool:\n");
705:                sb.append("     num of element =<" + count + ">\n");
706:                sb.append("     minSize =<" + minSize + ">\n");
707:                sb.append("     maxSize =<" + maxSize + ">\n");
708:                sb.append("     lifeTime =<" + lifeTime + ">\n");
709:                sb.append("     ngeneration =<" + generation + ">\n");
710:                sb.append("     maxLifeTime =<" + maxLifeTime + ">\n");
711:                sb.append("     getLockedObjectCount() =<"
712:                        + getLockedObjectCount() + ">\n");
713:                sb.append("     getUnlockedObjectCount() =<"
714:                        + getUnlockedObjectCount() + ">\n");
715:                sb.append("     getDeadLockMaxWait() =<" + getDeadLockMaxWait()
716:                        + ">\n");
717:                sb.append("     getDeadLockRetryWait() =<"
718:                        + getDeadLockRetryWait() + ">\n");
719:
720:                if (unlocked != null) {
721:                    sb.append("Unlocked pool:\n");
722:                    Enumeration e = unlocked.keys();
723:                    while (e.hasMoreElements()) {
724:                        GenerationObject o = (GenerationObject) e.nextElement();
725:                        sb.append(o.getObj().toString());
726:                    }
727:                }
728:
729:                if (locked != null) {
730:                    sb.append("Locked pool:\n");
731:                    Enumeration e = unlocked.keys();
732:                    while (e.hasMoreElements()) {
733:                        GenerationObject o = (GenerationObject) e.nextElement();
734:                        sb.append(o.getObj().toString());
735:                    }
736:                }
737:                return sb.toString();
738:            }
739:
740:            /**
741:             * Remove unusable objects from the pool, called by PoolKeeper Check the
742:             * unlocked objects for expired members.
743:             */
744:            protected void cleanUp() {
745:                // During shutdown, unlocked may be null.
746:                synchronized (this ) {
747:                    if (unlocked == null)
748:                        return;
749:                }
750:                long now = System.currentTimeMillis(); // current time
751:                synchronized (this ) {
752:                    for (Enumeration enumeration = unlocked.keys(); enumeration
753:                            .hasMoreElements();) { // for
754:                        // each
755:                        // object
756:                        // of
757:                        // the
758:                        GenerationObject o = (GenerationObject) enumeration
759:                                .nextElement();
760:                        // unlocked pool
761:
762:                        Long lasttouch = (Long) unlocked.get(o);
763:                        // birth day of the pool
764:                        if (lasttouch == null
765:                                || (now - lasttouch.longValue()) > lifeTime
766:                                || (maxLifeTime > 0 && (now - o.getCreated()) > maxLifeTime)) {
767:                            log.debug("GenericPool:cleanUp clean up the pool");
768:                            removeUnlockedObject(o);
769:                        }
770:                    }
771:                }
772:
773:                // Kill every object in the hit list. We do this outside synchronization
774:                // in case it takes too long. Note that hitList only grows so this is
775:                // a safe way to do this.
776:                while (hitList.size() > 0) { // kill each object.
777:                    // this might take a while, lets do it outside synchronization.
778:                    GenerationObject obj = (GenerationObject) hitList.remove(0);
779:                    log.debug("GenericPool:cleanUp killing an object");
780:                    poolHelper.expire(obj.getObj()); // try to "kill" it
781:                    obj.killObject();
782:                }
783:
784:                if (isGC()) // if the pool is GCeable
785:                    System.gc(); // launch system call to clean up unused objects
786:
787:                boolean resize = false;
788:                // Lets keep the look outside synchronization as object creation
789:                // may take a while.
790:                synchronized (this ) {
791:                    resize = count < minSize;
792:                }
793:
794:                if (resize) {
795:                    // if there is less than minSize objects in the pool
796:                    log
797:                            .info("GenericPool:cleanUp less than minSize objects in the pool "
798:                                    + "min="
799:                                    + minSize
800:                                    + " max="
801:                                    + maxSize
802:                                    + " count=" + count);
803:                    while (true) {
804:                        try {
805:                            GenerationObject genObject = poolHelper.create();
806:                            synchronized (this ) {
807:                                unlocked.put(genObject, new Long(now));
808:                                // put it in the unlocked pool
809:                                ++count; // there is one more element in the pool
810:                                notifyAll();
811:
812:                                if (count >= minSize)
813:                                    break;
814:                                // we want to make the test inside sync but leave the
815:                                // loop
816:                                // outside sync.
817:                            }
818:
819:                        } catch (Exception e) {
820:                            log
821:                                    .error("GenericPool:cleanUp   Could not create new connections to fill pool size to minSize.");
822:                            break; // ADDED THE BREAK SO WE DON't GET AN ENDLESS LOOP WHEN THE DATABASE IS DOWN.
823:                        }
824:                        synchronized (this ) {
825:                            notifyAll();
826:                        }
827:                    }
828:                    log.info("GenericPool:cleanUp done " + "min=" + minSize
829:                            + " max=" + maxSize + " count=" + count);
830:
831:                }
832:            }
833:
834:            /**
835:             * close all object in the unlocked and locked structures
836:             */
837:            void expireAll() {
838:                log
839:                        .debug("GenericPool:expireAll close all object in the unlocked and locked structures");
840:                for (Enumeration enumeration = unlocked.keys(); enumeration
841:                        .hasMoreElements();) { // for
842:                    // each
843:                    // object
844:                    // of
845:                    GenerationObject o = (GenerationObject) enumeration
846:                            .nextElement();
847:                    // the unlocked pool
848:                    poolHelper.expire(o.getObj()); // try to "kill" the object
849:                    o.killObject();
850:                    o = null;
851:                }
852:                for (Enumeration enumeration = locked.keys(); enumeration
853:                        .hasMoreElements();) { // for
854:                    // each
855:                    // object
856:                    // of
857:                    GenerationObject o = (GenerationObject) enumeration
858:                            .nextElement();
859:                    // the locked pool
860:                    poolHelper.expire(o.getObj()); // try to "kill" the object
861:                    o.killObject();
862:                    o = null;
863:                }
864:            }
865:
866:            /**
867:             * Allows to verify if objects from the pool - for the o generation - are
868:             * valid or not. (only for the unlocked pool, to avoid to allocate non-valid
869:             * object
870:             */
871:            public void nextGeneration(Object obj) {
872:                log.debug("GenericPool:nextGeneration");
873:                int genObj = 0;
874:                for (Enumeration enumeration = locked.keys(); enumeration
875:                        .hasMoreElements();) { // for
876:                    // each
877:                    // object
878:                    // of
879:                    GenerationObject o = (GenerationObject) enumeration
880:                            .nextElement();
881:                    // the locked pool
882:
883:                    if (o.getObj().equals(obj))
884:                        genObj = o.getGeneration(); // get the generation number
885:                }
886:
887:                for (Enumeration enumeration = unlocked.keys(); enumeration
888:                        .hasMoreElements();) { // for
889:                    // each
890:                    // object
891:                    // of
892:                    GenerationObject o = (GenerationObject) enumeration
893:                            .nextElement();
894:                    // the unlocked pool
895:
896:                    if (o.getGeneration() <= genObj) {
897:                        // all objects of the same generation
898:                        // or earlier are dropped
899:                        if (!poolHelper.checkThisObject(o.getObj()))
900:                            // if the object is not valid
901:                            removeUnlockedObject(o);
902:
903:                    }
904:                }
905:                ++this .generation; // now, we work with the next generation of object
906:
907:            }
908:
909:            /**
910:             * removes an object for the locked pool, when an error has occurred
911:             */
912:            synchronized public void removeLockedObject(Object obj) {
913:                log.debug("GenericPool:removeObject remove an object");
914:                for (Enumeration enumeration = locked.keys(); enumeration
915:                        .hasMoreElements();) { // for
916:                    // each
917:                    // object
918:                    // of
919:                    GenerationObject o = (GenerationObject) enumeration
920:                            .nextElement();
921:                    // the locked pool
922:                    System.out.println("GenericPool:removeObject "
923:                            + o.toString() + " - " + obj.toString());
924:
925:                    if (o.getObj().equals(obj)) {
926:                        System.out
927:                                .println("GenericPool:removeObject remove found");
928:                        locked.remove(o); // remove the object from the locked pool
929:                        --count;
930:                        o.killObject();
931:                        o = null;
932:                    }
933:                }
934:            }
935:
936:            /**
937:             * removes an object for the locked pool, when an error has occurred
938:             */
939:            synchronized public void fullRemoveLockedObject(Object obj) {
940:                log.debug("GenericPool:removeObject remove an object");
941:                for (Enumeration enumeration = locked.keys(); enumeration
942:                        .hasMoreElements();) { // for
943:                    // each
944:                    // object
945:                    // of
946:                    GenerationObject o = (GenerationObject) enumeration
947:                            .nextElement();
948:                    // the locked pool
949:                    System.out.println("GenericPool:removeObject "
950:                            + o.toString() + " - " + obj.toString());
951:
952:                    if (o.equals(obj)) {
953:
954:                        System.out
955:                                .println("GenericPool:removeObject remove found");
956:                        poolHelper.expire(o.getObj()); // try to "kill" it
957:
958:                        locked.remove(o); // remove the object from the locked pool
959:                        --count;
960:                        o.killObject();
961:                        o = null;
962:                    }
963:                }
964:            }
965:
966:            /**
967:             * Outputs a log message to the log writer.
968:             */
969:            public void setLogger(Logger alog) {
970:                log = alog;
971:            }
972:
973:            public Hashtable getLockedObject() {
974:                return locked;
975:
976:            }
977:
978:            public Hashtable getUnlockedPool() {
979:                return unlocked;
980:            }
981:
982:            public Hashtable getLockedPool() {
983:                return locked;
984:            }
985:
986:            public void setMaxLifeTime(long maxlifeTime) {
987:                this .maxLifeTime = maxlifeTime;
988:            }
989:
990:            public long getMaxLifeTime() {
991:                return maxLifeTime;
992:            }
993:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.