📄 objectpool.java
字号:
/* * PoolMan Java Object Pooling and Caching Library * Copyright (C) 1999-2001 The Code Studio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * The full license is located at the root of this distribution * in the LICENSE file. */package com.codestudio.util;import com.codestudio.PoolManConstants;import org.apache.log4j.Category;import org.apache.log4j.ConsoleAppender;import org.apache.log4j.DailyRollingFileAppender;import org.apache.log4j.PatternLayout;import java.io.IOException;import java.util.ArrayList;import java.util.Enumeration;import java.util.Hashtable;/** * ObjectPool provides a mechanism for pooling objects and resources. * It must be subclassed to create specific pools; GenericPool * and JDBCPool are examples of such subclasses. *<br> *@see GenericPool *@see JDBCPool */public abstract class ObjectPool implements com.codestudio.util.Pool { protected PoolMetaData metadata; protected int count; // quick count of total objects protected Hashtable locked; // objects checked out protected Hashtable unlocked; // objects available for checkout protected Thread skimmer; // thread to clean up dead objects protected Thread lifeguard; // thread to protect objects from hazard //protected PrintStream logger; /** Log4j handle */ protected Category logit; public ObjectPool(PoolMetaData metad) { this.metadata = metad; this.locked = new java.util.Hashtable(1); this.unlocked = new java.util.Hashtable(1); createLogger(); } private void createLogger() { logit = Category.getInstance(this.metadata.getName()); if (metadata.getLogFile() != null) { try { logit.addAppender(new DailyRollingFileAppender(new PatternLayout(), metadata.getLogFile(), "'.'yyyy-MM-dd")); } catch (IOException ioe) { System.out.println("Log file for " + metadata.getName() + " is invalid (" + metadata.getLogFile() + "): " + ioe); System.out.println("Logging that pool's info to the console"); logit.addAppender(new ConsoleAppender(new PatternLayout())); } } else { System.out.println("No log file indicated for " + metadata.getName() + ", logging that pool's info to the console"); logit.addAppender(new ConsoleAppender(new PatternLayout())); } /* OLD PRE-log4j CODE // set up the logger if (metadata.getLogFile() == null) { this.logger = new PrintStream(System.out); } else { try { String fileName = metadata.getLogFile(); FileOutputStream fileOut = new FileOutputStream(fileName); this.logger = new PrintStream(fileOut, true); } catch (Exception e) { System.err.println("Unable to open log file named \"" + metadata.getLogFile() + "\" using System.out instead"); this.logger = new PrintStream(System.out); } } */ } public void init() throws Exception { // create the initial objects if (metadata.getInitialObjects() > 0) { debug("Creating " + metadata.getInitialObjects() + " initial objects in pool " + metadata.getName()); ArrayList initialObjects = new ArrayList(); for (int i = 0; i < metadata.getInitialObjects(); i++) { initialObjects.add(checkOut()); } for (int i = 0; i < initialObjects.size(); i++) { checkIn(initialObjects.get(i)); } debug("Completed creation of initial objects"); } // skimmer removes dead or useless objects debug("Starting PoolSkimmer, which will expire objects after the <skimmerFrequency> element " + "(currently set to " + metadata.getSkimmerFrequency() + " seconds)"); this.skimmer = new Thread(new PoolSkimmerThread(metadata.getSkimmerFrequency(), this)); skimmer.setDaemon(true); skimmer.start(); // lifeguard returns checked out object to pool if (metadata.getUserTimeout() > 0) { debug("Starting LifeGuard, which will return checked-out objects to their pools if they are held " + "longer than the <userTimeout> element " + "(currently set to " + metadata.getUserTimeout() + " seconds)"); this.lifeguard = new Thread(new LifeGuardThread(metadata.getUserTimeout(), this)); lifeguard.setDaemon(true); lifeguard.start(); } else { debug("Not starting LifeGuard, as the user timeout element is zero or less. " + "Objects will NOT automatically return to their pools, and must be " + "explicitly closed or returned."); } } protected abstract Object create() throws Exception; protected abstract boolean validate(Object o); /** Default expiration invokes <code>PooledObject.closeAllResources()</code> */ protected void expire(Object o) { if (o instanceof com.codestudio.util.PooledObject) ((com.codestudio.util.PooledObject) o).closeAllResources(); } public String getPoolname() { return metadata.getName(); } /** Subclasses will usually want to override this method. */ public Object requestObject() { try { return checkOut(); } catch (Exception e) { } return null; } /** * Subclasses will usually want to override this method, at least * for type safety. */ public void returnObject(Object o) { checkIn(o); } /** @return int The total number of objects in the pool, both locked and unlocked. */ public synchronized int numTotalObjects() { return this.count; } /** @return int The number of objects currently available. */ public synchronized int numCheckedOutObjects() { return locked.size(); } /** @return int The number of objects currently checked out. */ public synchronized int numCheckedInObjects() { return unlocked.size(); } /** * Checkout cycles through the available objects and returns the first valid * object it finds. if there are no valid objects, checkOut will create * one, unless the client specified amount of objects have already been * created, and then it will block until it finds an appropriate object * @returns Object an instance of the object type that this pool holds */ protected synchronized Object checkOut() throws Exception { long now = System.currentTimeMillis(); Object o = null; if (unlocked.size() > 0) { for (Enumeration e = unlocked.keys(); e.hasMoreElements();) { o = e.nextElement(); if (validate(o)) { unlocked.remove(o); locked.put(o, new Long(now)); break; } else { // object failed validation --count; unlocked.remove(o); expire(o); o = null; } } } if (o != null) { debug("PoolMan ObjectPool: returned existing pooled object for request"); debugMetrics(); return o; } // no objects available, but can create a new one if (count < metadata.getMaximumSize()) { // there is still room for objects
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -