⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objectpool.java

📁 java编写的数据库连接池的源代码。包含有连接池的源码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * Object creation method.
	 * This method is called when a new item needs to be created following a call
	 * to one of the check-out methods.
	 * @exception Exception if unable to create the item
	 */
	protected abstract Reusable create() throws Exception;

	/**
	 * Object validation method.
	 * This method is called when checking-out an item to see if it is valid for use.
	 * When overridden by the sub-class it is recommended that this method perform
	 * suitable checks to ensure the object can be used without problems.
	 */
	protected abstract boolean isValid(final Reusable o);

	/**
	 * Object destruction method.
	 * This method is called when an object needs to be destroyed due to pool
	 * pruning/cleaning, or final release of the pool.
	 */
	protected abstract void destroy(final Reusable o);

	/**
	 * Destroys the given object (asynchronously if necessary).
	 */
	private final void destroyObject(final Reusable o)
	{
		if (o == null)
			return;
		if (asyncDestroy)
		{
			Thread t = new Thread(new Runnable()
			{
				public void run() { destroy(o); }
			});
			t.start();
		}
		else
			destroy(o);
	}

	/**
	 * Determines whether to perform asynchronous object destruction.
	 * If set to true then each time an object is destroyed (invalid object
	 * during pool operation, or when the pool is finally released) the operation
	 * is done in a separate thread, allowing the method to return immediately.
	 * This can be useful when calling the destroy method on an object takes a
	 * long time to complete.
	 */
	public final void setAsyncDestroy(boolean b) { asyncDestroy = b; }

	/**
	 * Returns whether asynchronous object destruction is enabled.
	 * (Default: false)
	 */
	public final boolean isAsyncDestroy() { return asyncDestroy; }

	/**
	 * Writes a message to the log.
	 */
	public void log(String logEntry)
	{
		log(name + ": ", logEntry);
	}

	/**
	 * Writes a message with an Exception to the log file.
	 */
	public void log(Throwable e, String logEntry)
	{
		log(e, name + ": ", logEntry);
	}

	/**
	 * Returns the pool name.
	 */
	public final String getName() { return this.name; }

	/**
	 * Returns the maximum size of the pool.
	 */
	public final int getPoolSize() { return poolSize; }

	/**
	 * Returns the maximum number of items that can be created.
	 */
	public final int getMaxSize() { return maxSize; }

	/**
	 * Returns the expiry time for unused items in the pool.
	 */
	public final long getExpiryTime() { return expiryTime; }

	/**
	 * Sets the pooling parameters.
	 * Any items currently in the pool will remain, subject to the new parameters.
	 * (The hit rate counters are reset when this method is called.)
	 * @param poolSize number of items to be keep in pool
	 * @param maxSize maximum number of items to be created
	 * @param expiryTime expiry time for unused items (milliseconds) (0 = no expiry)
	 */
	public final void setParameters(int poolSize, int maxSize, long expiryTime)
	{
		synchronized(this)
		{
			if (cleaner != null)
				cleaner.halt();

			this.poolSize = Math.max(poolSize, 0);
			this.maxSize = Math.max(maxSize, 0);
			this.expiryTime = Math.max(expiryTime, 0);
			if (this.maxSize > 0  &&  this.maxSize < this.poolSize)
				this.maxSize = this.poolSize;
			resetHitCounter();
			
			//  Update pooled items to use new expiry
			Iterator iter = free.iterator();
			TimeWrapper tw = null;
			while (iter.hasNext())
			{
				tw = (TimeWrapper)iter.next();
				tw.setLiveTime(expiryTime);
			}
			//  Creates cleaner thread with check interval of at most 5 seconds.
			if (this.expiryTime > 0)
			{
				long iVal = Math.min(5000, this.expiryTime / 5);
				(cleaner = new Cleaner(this, iVal)).start();
			}
		}
		if (debug)
		{
			String info = "pool=" + this.poolSize + ",max=" + this.maxSize + ",expiry=";
			info += this.expiryTime == 0 ? "none" : this.expiryTime + "ms";
			log("Parameters changed (" + info + ")");
		}
		if (listeners != null)
			fireParametersChangedEvent();
	}

	/**
	 * Returns the total number of objects held (available and checked-out).
	 */
	public final synchronized int getSize() { return free.size() + used.size(); }

	/**
	 * Returns the number of items that are currently checked-out.
	 */
	public final synchronized int getCheckedOut() { return used.size(); }

	/**
	 * Returns the number of items held in the pool that are free to be checked-out.
	 */
	public final synchronized int getFreeCount() { return free.size(); }

	/**
	 * Returns hit rate of the pool as a percentage.
	 * The hit rate is the proportion of requests for a connection which result
	 * in the return of a connection which is in the pool, rather than which
	 * results in the creation of a new connection.
	 */
	public final float getHitRate() { return (requests == 0) ? 0 : (((float)hits / requests) * 100f); }

	/**
	 * Resets the counter for determining the pool's hit rate.
	 */
	protected final void resetHitCounter() { requests = hits = 0; }

	/**
	 * Returns the class to use for the pool collection.
	 * This can be over-ridden by a sub-class to provide a different List
	 * type for the pool, which may give performance benefits in certain situations.
	 * Only instances of List collections should be used.
	 * (Default: java.util.ArrayList.class)
	 * For those wanting to override this method, pool items are checked-out from
	 * the front of the List - <tt>remove(0)</tt> - and replaced at the end of
	 * the List when checked-in again - <tt>add(Object)</tt>.
	 */
	protected Class getPoolClass() { return ArrayList.class; }

	/**
	 * Shuts down the object pool.
	 * If overridden the sub-class should make sure super.finalize() is called.
	 */
	public void finalize()
	{
		if (cleaner != null)
		{
			cleaner.halt();
			cleaner = null;
		}
	}

	/**
	 * Flushes the pool of all currently available items.
	 */
	public final void flush()
	{
		int count = 0;
		synchronized(this)
		{
			Iterator iter = free.iterator();
			TimeWrapper tw = null;
			while (iter.hasNext())
			{
				tw = (TimeWrapper)iter.next();
				iter.remove();
				destroyObject((Reusable)tw.getObject());
				count++;
			}
		}
		if (count > 0  &&  debug)
			log("Flushed all spare items from pool");
	}

	/**
	 * Purges expired objects from the pool.
	 * This method is called by the cleaner thread to purge expired items.
	 * @return false if pool is empty after purging (no further purge required until items added), true otherwise
	 */
	final synchronized boolean purge()
	{
		if (debug)
			log("Checking for expired items");
		int count = 0;
		Iterator iter = free.iterator();
		TimeWrapper tw = null;
		while (iter.hasNext())
		{
			tw = (TimeWrapper)iter.next();
			if (tw.isExpired())
			{
				iter.remove();
				destroyObject((Reusable)tw.getObject());
				count++;
			}
		}
		return free.size() > 0  ||  count > 0;
	}
	
	//**************************
	//  Event-handling methods
	//**************************

	/**
	 * Adds an ObjectPoolListener to the event notification list.
	 */
	public final void addObjectPoolListener(ObjectPoolListener x)
	{
		listeners.add(x);
	}

	/**
	 * Removes an ObjectPoolListener from the event notification list.
	 */
	public final void removeObjectPoolListener(ObjectPoolListener x)
	{
		listeners.remove(x);
	}

	private final void firePoolCheckOutEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.CHECKOUT);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).poolCheckOut(poolEvent);
	}

	private final void firePoolCheckInEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.CHECKIN);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).poolCheckIn(poolEvent);
	}

	private final void fireMaxPoolLimitReachedEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.MAX_POOL_LIMIT_REACHED);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).maxPoolLimitReached(poolEvent);
	}

	private final void fireMaxPoolLimitExceededEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.MAX_POOL_LIMIT_EXCEEDED);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).maxPoolLimitExceeded(poolEvent);
	}

	private final void fireMaxSizeLimitReachedEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.MAX_SIZE_LIMIT_REACHED);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).maxSizeLimitReached(poolEvent);
	}

	private final void fireMaxSizeLimitErrorEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.MAX_SIZE_LIMIT_ERROR);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).maxSizeLimitError(poolEvent);
	}

	private final void fireParametersChangedEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.PARAMETERS_CHANGED);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).poolParametersChanged(poolEvent);
	}

	private final void firePoolReleasedEvent()
	{
		ObjectPoolEvent poolEvent = new ObjectPoolEvent(this, ObjectPoolEvent.POOL_RELEASED);
		for (Iterator iter = listeners.iterator(); iter.hasNext();)
			((ObjectPoolListener)iter.next()).poolReleased(poolEvent);
	}
	
	
	/**
	 * Thread to perform clean-up of expired objects in pool.
	 * Each time nothing is cleaned because the pool is empty the cleaner waits
	 * until an item is returned, when it is woken up and starts cleaning again.
	 */
	final class Cleaner extends Thread
	{
		private ObjectPool pool;
		private long interval;
		private boolean stopped;

		Cleaner(ObjectPool pool, long interval)
		{
			this.setName("CleanerThread" + Integer.toString(cleanerCount++));
			this.pool = pool;
			this.interval = interval;
		}

		public void start()
		{
			stopped = false;
			super.start();
		}

		/**
		 * Safely stops the thread from running.
		 */
		public void halt()
		{
			if (!isHalted())
			{
				stopped = true;
				interrupt();  // Wake cleaner if necessary
			}
		}

		/**
		 * Returns whether the thread has been halted.
		 */
		public boolean isHalted() { return stopped; }

		/**
		 * Handles the expiry of old objects.
		 */
		public void run()
		{
			while (pool.cleaner == Thread.currentThread()  &&  !stopped)
			{
				synchronized(pool)
				{
					if (!pool.purge())
					{
						try { pool.wait(); }
						catch (InterruptedException e) {}
					}
				}
				if (!stopped)
				{
					try { sleep(interval); }
					catch (InterruptedException e) {}
				}
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -