Java连接池实现
如果可以实现它,你能看看我的连接池吗?
public class ConnectionPool { private static List pool = null; private static int available = 0; private ConnectionPool() {} public static DBConnection getConnection() { if (pool == null) { pool = new ArrayList(); for (int i = 0; i 0) { available--; return pool.remove(available); } else { return null; } } public static void returnConnection(DBConnection c) { pool.add(c); available++; } }
我只使用一个数组,客户端应该要求连接池使用连接,然后将其返回到连接池。
Connection connection = ConnectionPool.getConnection(); connection.execute("insert into users values('"+user.getUsername()+"', '"+user.getPassword()+"', '"+user.getGroup()+"', '"+banned+"', '"+broker+admin+sharehodler+company+"')"); ConnectionPool.returnConnection(connection); connection = null;
我需要有关此实施的反馈。 谢谢
有一些观点使这种实现很成问题。
- 线程安全。 如果几个线程与池一起工作怎么办? 您没有将列表锁定在读/写访问权限上。
- 静态最大池大小为3个连接,您也可以立即创建所有这些连接,无论它们是否需要。 一种常见的策略是创建一堆连接并在需要时创建更多连接,直到达到允许/配置的最大值。
- 你只有静态方法。 应该可以有多个池,这意味着您需要
ConnectionPool
实例。 - 无法将host + dbname + user + password传递给创建的连接。
- 您没有处理“断开”连接 – 如果现有连接搞砸了,您可能需要重新创建连接。 这比我开始使用池之前想象的要重要得多。
- 使用配置值而不是静态值,请参阅第2点
- 最后:确定,自己编写这些内容很有意思 – 但如果您需要一个项目池,请选择一个现有的池,例如c3p0或tomcat连接池 。
我确信还有更多要点,但除非这些是固定的,否则继续没有用处。
池实现的一个大问题是您将裸连接传递给池的调用者。 这意味着有人可以从您的池中获取连接,关闭它,然后将其返回到池中。 这很糟糕 。
解决此问题的常用方法是使用委托包装返回连接对象,并使它们忽略对close方法的调用(或者甚至更好,使close()安全地返回到池的底层连接)。
其他主要问题:
- 如果在事务中间返回连接会发生什么?
- 如果连接以某种方式损坏或断开连接会发生什么? 它留在游泳池吗?
总而言之,您应该重用现有的连接池实现,而不是自己编写。 目前,许多类型4的驱动程序都在驱动程序中包含自己的连接池。
一些想法:
- 您的代码不是线程安全的。 也许就此工作吧。
- getConnection()中的代码太多。 懒惰的初始化真的需要吗?
- 可用是无用的,可以用pool.size()代替。
据我所知,
-
您的
getConnection()
方法需要更改为仅检索Connection
对象。准备连接和池应该从getConnection()方法中删除,并以第一次加载
ConnectionPool
类时的方式添加。此外,您还需要处理其他一些属性,如
connection timeout
,purging
等,以使其适用于所有方案。使它也是线程安全的。