`

连接池实现方法学习

阅读更多
import java.sql.*;
import java.lang.reflect.*;
import java.util.*;
import java.io.*;


/**
 * 配合动态代理来学习
 * 2010-12-13
 */
public class SimpleConnetionPool {
	private static LinkedList m_notUsedConnection = new LinkedList();
	private static HashSet m_usedUsedConnection = new HashSet();
	private static String m_url = "";
	private static String m_user = "";
	private static String m_password = "";
	static final boolean DEBUG = true;
	static private long m_lastClearClosedConnection = System.currentTimeMillis();
	public static long CHECK_CLOSED_CONNECTION_TIME = 4 * 60 * 60 * 1000; // 4
	// hours

	static {
		initDriver();
	}

	private SimpleConnetionPool() {
	}

	private static void initDriver() {
		Driver driver = null;
		// load mysql driver
		try {
			driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();
			installDriver(driver);
		} catch (Exception e) {
		}

		// load postgresql driver
		try {
			driver = (Driver) Class.forName("org.postgresql.Driver").newInstance();
			installDriver(driver);
		} catch (Exception e) {
		}
	}

	public static void installDriver(Driver driver) {
		try {
			DriverManager.registerDriver(driver);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static synchronized Connection getConnection() {
		clearClosedConnection();
		while (m_notUsedConnection.size() > 0) {
			try {
				ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst();
				if (wrapper.connection.isClosed()) {
					continue;
				}
				m_usedUsedConnection.add(wrapper);
				if (DEBUG) {
					wrapper.debugInfo = new Throwable("Connection initial statement");
				}
				return wrapper.connection;
			} catch (Exception e) {
			}
		}
		int newCount = getIncreasingConnectionCount();
		LinkedList list = new LinkedList();
		ConnectionWrapper wrapper = null;
		for (int i = 0; i < newCount; i++) {
			wrapper = getNewConnection();
			if (wrapper != null) {
				list.add(wrapper);
			}
		}
		if (list.size() == 0) {
			return null;
		}
		wrapper = (ConnectionWrapper) list.removeFirst();
		m_usedUsedConnection.add(wrapper);

		m_notUsedConnection.addAll(list);
		list.clear();

		return wrapper.connection;
	}

	private static ConnectionWrapper getNewConnection() {
		try {
			Connection con = DriverManager.getConnection(m_url, m_user, m_password);
			ConnectionWrapper wrapper = new ConnectionWrapper(con);
			return wrapper;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	static synchronized void pushConnectionBackToPool(ConnectionWrapper con) {
		boolean exist = m_usedUsedConnection.remove(con);
		if (exist) {
			m_notUsedConnection.addLast(con);
		}
	}

	public static int close() {
		int count = 0;

		Iterator iterator = m_notUsedConnection.iterator();
		while (iterator.hasNext()) {
			try {
				((ConnectionWrapper) iterator.next()).close();
				count++;
			} catch (Exception e) {
			}
		}
		m_notUsedConnection.clear();

		iterator = m_usedUsedConnection.iterator();
		while (iterator.hasNext()) {
			try {
				ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
				wrapper.close();
				if (DEBUG) {
					wrapper.debugInfo.printStackTrace();
				}
				count++;
			} catch (Exception e) {
			}
		}
		m_usedUsedConnection.clear();

		return count;
	}

	private static void clearClosedConnection() {
		long time = System.currentTimeMillis();
		// sometimes user change system time,just return
		if (time < m_lastClearClosedConnection) {
			time = m_lastClearClosedConnection;
			return;
		}
		// no need check very often
		if (time - m_lastClearClosedConnection < CHECK_CLOSED_CONNECTION_TIME) {
			return;
		}
		m_lastClearClosedConnection = time;

		// begin check
		Iterator iterator = m_notUsedConnection.iterator();
		while (iterator.hasNext()) {
			ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
			try {
				if (wrapper.connection.isClosed()) {
					iterator.remove();
				}
			} catch (Exception e) {
				iterator.remove();
				if (DEBUG) {
					System.out.println("connection is closed, this connection initial StackTrace");
					wrapper.debugInfo.printStackTrace();
				}
			}
		}

		// make connection pool size smaller if too big
		int decrease = getDecreasingConnectionCount();
		if (m_notUsedConnection.size() < decrease) {
			return;
		}

		while (decrease-- > 0) {
			ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.removeFirst();
			try {
				wrapper.connection.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * get increasing connection count, not just add 1 connection
	 * 
	 * @return count
	 */
	public static int getIncreasingConnectionCount() {
		int count = 1;
		int current = getConnectionCount();
		count = current / 4;
		if (count < 1) {
			count = 1;
		}
		return count;
	}

	/**
	 * get decreasing connection count, not just remove 1 connection
	 * 
	 * @return count
	 */
	public static int getDecreasingConnectionCount() {
		int count = 0;
		int current = getConnectionCount();
		if (current < 10) {
			return 0;
		}
		return current / 3;
	}

	public synchronized static void printDebugMsg() {
		printDebugMsg(System.out);
	}

	public synchronized static void printDebugMsg(PrintStream out) {
		if (DEBUG == false) {
			return;
		}
		StringBuffer msg = new StringBuffer();
		msg.append("debug message in " + SimpleConnetionPool.class.getName());
		msg.append("\r\n");
		msg.append("total count is connection pool: " + getConnectionCount());
		msg.append("\r\n");
		msg.append("not used connection count: " + getNotUsedConnectionCount());
		msg.append("\r\n");
		msg.append("used connection, count: " + getUsedConnectionCount());
		out.println(msg);
		Iterator iterator = m_usedUsedConnection.iterator();
		while (iterator.hasNext()) {
			ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
			wrapper.debugInfo.printStackTrace(out);
		}
		out.println();
	}

	public static synchronized int getNotUsedConnectionCount() {
		return m_notUsedConnection.size();
	}

	public static synchronized int getUsedConnectionCount() {
		return m_usedUsedConnection.size();
	}

	public static synchronized int getConnectionCount() {
		return m_notUsedConnection.size() + m_usedUsedConnection.size();
	}

	public static String getUrl() {
		return m_url;
	}

	public static void setUrl(String url) {
		if (url == null) {
			return;
		}
		m_url = url.trim();
	}

	public static String getUser() {
		return m_user;
	}

	public static void setUser(String user) {
		if (user == null) {
			return;
		}
		m_user = user.trim();
	}

	public static String getPassword() {
		return m_password;
	}

	public static void setPassword(String password) {
		if (password == null) {
			return;
		}
		m_password = password.trim();
	}

}

class ConnectionWrapper implements InvocationHandler {
	private final static String CLOSE_METHOD_NAME = "close";
	public Connection connection = null;
	private Connection m_originConnection = null;
	public long lastAccessTime = System.currentTimeMillis();
	Throwable debugInfo = new Throwable("Connection initial statement");

	ConnectionWrapper(Connection con) {
		this.connection = (Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), con.getClass().getInterfaces(), this);
		m_originConnection = con;
	}

	void close() throws SQLException {
		m_originConnection.close();
	}

	public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
		Object obj = null;
		if (CLOSE_METHOD_NAME.equals(m.getName())) {
			SimpleConnetionPool.pushConnectionBackToPool(this);
		} else {
			obj = m.invoke(m_originConnection, args);
		}
		lastAccessTime = System.currentTimeMillis();
		return obj;
	}
}
 
分享到:
评论

相关推荐

    C#高效数据库连接池源码

    `ConnectionPool`可能是项目或类库的命名空间或类,包含实际的数据库连接池实现;`Demo`可能是一个示例应用程序,展示如何使用自定义的数据库连接池。 5. **连接池实现细节**: - **初始化**:在应用程序启动时,...

    delphi实现数据库连接池

    开发者可以通过阅读和理解这些代码,学习如何在自己的应用中实现高效的数据库连接池机制。 总的来说,Delphi实现数据库连接池是一项关键的技术,对于优化数据库访问效率和系统整体性能有着显著的影响。正确地设计和...

    数据库连接池的实现(很完整(支持多种数据库

    综上所述,这个压缩包提供了一个全面的数据库连接池实现,适用于多种数据库,包括源码和测试,对于学习和开发数据库相关的应用程序具有很高的价值。通过研究和使用这个实现,开发者可以更好地理解和优化自己项目的...

    MySql数据库连接池C#代码(有注释含测试代码)

    总的来说,这个代码示例提供了一个基础的MySQL数据库连接池实现,可以作为学习和开发的起点。然而,正如描述中提到的,代码可能存在优化空间,比如错误处理、性能调优等方面,建议开发者根据具体需求进行修改和完善...

    基于Swoole的通用连接池实现常用来作为数据库连接池

    “基于Swoole的通用连接池实现常用来作为数据库连接池” 这个标题指出了一个关键的编程实践,即利用Swoole扩展在PHP中构建一个通用的连接池,特别是用于管理数据库连接。Swoole是一个高性能的PHP扩展,它提供了异步...

    BoneCP 连接池学习笔记

    通过上述介绍,我们可以看出 BoneCP 是一个优秀的连接池实现,特别适合处理大量并发请求。学习和掌握 BoneCP 的使用,能够帮助我们构建更高效、稳定的数据库驱动的应用程序。阅读 "BoneCP 连接池.doc" 文件,可以...

    Java对JDBC连接池的实现

    这是我写的一个对JDBC连接池的实现,高手见了可不要笑啊!!!! 程序是在linux下用Eclipse下编写的. 用Jude进行建模,数据库使用了mysql. 程序自带了MySql的Connection连接驱动类,你也可以使用别的驱动类和数据库, 在src/...

    Java 连接池源码

    在Java中,常见的连接池实现有Apache的DBCP、C3P0,还有更现代的HikariCP。这些库都提供了高效的连接管理和自动回收功能。然而,了解连接池的内部工作原理对于优化数据库操作和解决相关问题至关重要。 个人实现Java...

    数据库连接池的原理机制学习

    不过,这些服务器通常需要额外的第三方组件或者自定义的类来实现具体的连接池操作。 #### 三、连接池关键问题分析 1. **并发问题**:在多线程环境下,确保连接池的线程安全性至关重要。Java通过`synchronized`...

    简单的jdbc连接池类

    总之,这个简单的jdbc连接池类实现了基础的数据库连接管理,对于学习数据库连接池的工作原理和编写自己的连接池实现非常有帮助。虽然它的功能可能不如商业级连接池强大,但对于小型项目或教学示例来说,已经足够实用...

    mysql连接池java源码

    MySQL连接池在Java应用开发中扮演着至关重要的角色...总的来说,这个项目提供了一个学习和研究数据库连接池实现的绝佳机会,通过分析和实践,开发者可以更好地掌握数据库连接管理的技巧,提高Java应用的性能和稳定性。

    简单版连接池操作数据库增删改(适合新手学习)

    在Java中,常见的连接池实现有Apache的DBCP、C3P0、HikariCP以及Spring框架的DataSource等。这里我们可能使用的是一个简化版的连接池实现,用于教学目的。 对于新手来说,首先需要理解数据库连接的生命周期:打开...

    连接池源码和视频教程

    - DBCP(DBCP2):Apache基础库提供的连接池实现,相对简单,但功能可能不如C3P0全面。 - HikariCP:目前被认为是性能最佳的Java连接池,它的设计目标是低延迟和高性能。HikariCP在内部使用了高效的对象池设计。 ...

    C# Socket连接池

    在压缩包文件"NetPool"中,可能包含了实现C# Socket连接池的源代码,你可以通过阅读和学习这些代码,进一步了解如何结合线程池技术来构建自己的Socket连接池。同时,别忘了使用Windows性能计数器来监控你的系统,...

    IPC方式之Binder连接池

    学习这个DEMO,你可以了解如何实现Binder连接池,以及如何在实际项目中应用它来优化IPC性能。通过对Binder连接池的掌握,能够提升应用的响应速度,降低系统资源消耗,尤其对于大型应用或高性能要求的场景,这一点尤...

    简易的数据库连接池实现

    自定义实现的数据库连接池,并进行加锁,保证线程安全,适合初学者学习。

    JAVA数据库连接池

    本教程将深入探讨数据库连接池的原理,特别是针对C3P0和DBCP这两个常见的连接池实现。 首先,我们来看一下数据库连接池的基本概念。数据库连接池在初始化时会创建一定数量的数据库连接并保存在池中,当应用程序需要...

    实现数据库连接池

    通过阅读和理解这些源码,我们可以学习到如何在Java中实现数据库连接池的细节,包括如何使用线程安全的数据结构来管理连接,如何处理并发访问,以及如何设计高效的连接分配和回收策略。这对于提升Java应用的数据库...

    数据库连接池案例包括c3p0,druid,和自己手写的连接池

    本案例将介绍三种常见的数据库连接池实现:C3P0、Druid以及自定义连接池的实现。 首先,C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0的主要特性包括连接测试、...

Global site tag (gtag.js) - Google Analytics