`
nishijia
  • 浏览: 53108 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

自己写了个连接池

    博客分类:
  • JDBC
阅读更多

自己写了个连接池,不过性能不理想,当模拟1000个线程去连接数据库时,会在getConnection这个方法里爆出空指针。

 

oracle的配置文件:

 

driver = oracle.jdbc.driver.OracleDriver
url = jdbc:oracle:thin:@localhost:1521:DB
user = username
password = pwd
defaultRowPrefetch=50
defaultExecuteBatch=25
poolsize=20
islation=2

 

连接池:

package com.connection;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;

import java.util.Map;
import java.util.Properties;

import com.util.PropertiesHelper;

import oracle.jdbc.driver.OracleConnection;

public class ConnectionPool {
	private static Map<Connection, Boolean> pool = new HashMap<Connection, Boolean>();
	
	public static DataBase db=null;
	
	private static Properties prop;

	private static int POOLSIZE = 5;


	public static synchronized void init(String file){
		if (pool.size() == 0) {
			try {
				
				prop = readProperties(file);
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				Class.forName(prop.getProperty("driver"));
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
			if (prop.getProperty("poolsize").length() > 0)
				POOLSIZE = Integer.parseInt(prop.getProperty("poolsize"));

			for (int i = 0; i < POOLSIZE; i++) {
				pool.put(newConnection(), true);
			}
		}
	}

	private static synchronized Connection newConnection() {
		Connection conn=null;
		try {
			String url=prop.getProperty("url");
			conn = DriverManager.getConnection(url, prop);
			conn.setTransactionIsolation(Integer.parseInt(prop.getProperty("islation")));
			conn.setAutoCommit(false);
			} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	

	
	public static void closeAll() {
		for (Connection c : pool.keySet()) {
			try {
				c.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public static Connection getConnection() {
		synchronized (pool) {
			for (Connection conn : pool.keySet()) {
				if (pool.get(conn) == false) {
					pool.put(conn, true);
					return conn;
				}
			}
		}
		Connection c=newConnection();
		return c;
	}

	public static void release(Connection conn) {
		if (conn != null) {
			synchronized (pool) {
				if (!pool.keySet().contains(conn)) {
					try {
						conn.close();
					} catch (SQLException e) {
						throw new RuntimeException(e);
					}
				} else
					pool.put(conn, false);
			}
		}
	}

	public static void closePool() {
		for (Connection conn  : pool.keySet()) {
			try {
				conn.close();
				pool.clear();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	private static Properties readProperties(String file) throws IOException {
		Properties result = new Properties();
		InputStream is = ConnectionPool.class.getClassLoader()
				.getResourceAsStream(file);
		result.load(is);
		return result;
	}
}

 

测试代码:

 

package com.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.connection.ConnectionPool;
import com.dao.BaseDAO;

public class Test extends Thread{
	
	 private String sql;  
	      
	     private Connection c;  
	     public Test(Connection c,String sql){  
	         
	         this.c=c;  
	         this.sql=sql;  
	     }  
	
	  public static void main(String[] args) {  
		  ConnectionPool.init("oracle.properties"); 
		 
		         for(int i=0;i<100;i++){  
		             String sql="select sysdate from dual";  
		             new Test(ConnectionPool.getConnection(),sql).start();  
		         }  
		   
		     }  
		       
		     public void run(){  
		         try {  
		             System.out.println(c);
		        	 ResultSet rs=c.createStatement().executeQuery(sql);  
		             while(rs.next()){  
		                 System.out.println(rs.getString(1));  
		             }  
		             
		         } catch (SQLException e) {  
		             e.printStackTrace();  
		         }finally{  
		        	 ConnectionPool.release(c);  
		         }  
		     }  
}

 

 

模拟100个线程完全没问题,但是数量一旦上去了就不行了  连接池得不到连接了。

 

我的思路是当你请求一个资源,池会看看池中有没有资源,有的话把这个资源分发给请求,没有的话,生成新的资源同时把该资源放到池中。当请求归还的时候,池会判断池中是否满了,如果满了,那么释放该资源。其中关键的,就是生成新资源,判断是否释放资源。

 

我自己写是为了多学点知识  一直用别人封装好的连接池  没什么意思,个人写的很烂,欢迎有技术性的建议。

分享到:
评论
10 楼 nishijia 2009-11-23  
maomiandyou 写道
lz
你的代码
我测试3000都没问题
??
你改过了?


我的代码在oracle 用户多了就有问题 MYSQL 没试过
9 楼 maomiandyou 2009-11-16  
lz
你的代码
我测试3000都没问题
??
你改过了?
8 楼 mathgl 2009-08-21  
用 blockingqueue 放conn不错。。
7 楼 猪也有理想 2009-08-20  
<div class="quote_title">zxmsdyz 写道</div>
<div class="quote_div">
<div class="quote_title">unsid 写道</div>
<div class="quote_div">两个建议:<br>1、getConnection中,如果池内没有连接则新建一个,新建的又不归池管,那连接池还有什么意义?应该判断如果池内连接全部占用则判断池连接数是否达到最大,如果最大了则阻塞wait,直到有人释放了连接才notify;如果没到,则新建一个连接放在池内并返回<br><br>2、release用来释放连接非常不好,因为很多习惯conn.close()写,导致了连接池中连接收不回来,应该创建连接的时候用Proxy重写Connection的close方法,在其中将true改成false</div>
<br><br>第二个明白了,第一条怎么做的呢,能否详细讲讲</div>
<p> </p>
<p> </p>
<p>unsid的意思是你做连接池的时候建立一个新的连接。然后把该连接存放起来,下次在连接的时候先判断是否有空闲的连接。如果有直接拿来用</p>
<p>如果没有。在判断是否超过了最大连接数,如果没超过。则重新创建一个新的连接,如超过。则等待</p>
<p> </p>
6 楼 猪也有理想 2009-08-20  
<p>MYsql做DEMO演示下给你</p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>首先在SRC下面建立一个db.properties文件.,内容如下:</p>
<p> </p>
<pre name="code" class="java">drivers=com.mysql.jdbc.Driver
logfile=D:\\log.txt
mysql.url=jdbc:mysql://127.0.0.1:3306/blog?characterEncoding=gb2312
mysql.maxconn=1
mysql.user=root
mysql.password=root</pre>
<p><span style="color: #0000ff;">drivers 以空格分隔的JDBC驱动程序类列表<br>logfile 日志文件的绝对路径<br><br>其它的属性和特定连接池相关,其属性名字前应加上连接池名字:<br><br>&lt;poolname&gt;.url 数据库的 JDBC URL <br>&lt;poolname&gt;.maxconn 允许建立的最大连接数,0表示没有限制 <br>&lt;poolname&gt;.user 用于该连接池的数据库帐号<br>&lt;poolname&gt;.password 相应的密码</span></p>
<p> </p>
<p> </p>
<p>其中url属性是必需的,而其它属性则是可选的。数据库帐号和密码必须合法。</p>
<p> </p>
<p> </p>
<p>获得连接处理代码:</p>
<p> </p>
<pre name="code" class="java">public class DBManager {

private Connection conn ;
private String poolURL = "";
private String driverName ="";
private String user="" ;
private String pass="";
static private DBManager instance; // 唯一实例
static private int clients;
private Vector drivers = new Vector();
private PrintWriter log;
private Hashtable pools = new Hashtable();

/**
* 返回唯一实例.如果是第一次调用此方法,则创建实例
*
* @return DBConnectionManager 唯一实例
*/
static synchronized public DBManager getInstance() {
if (instance == null) {
instance = new DBManager();
}
clients++;
return instance;
}

/**
* 建构函数私有以防止其它对象创建本类实例
*/
private DBManager() {
init();
}

/**
* 将连接对象返回给由名字指定的连接池
*
* @param name 在属性文件中定义的连接池名字
* @param con 连接对象
*/
public void freeConnection(String name, Connection con) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
pool.freeConnection(con);
}
}

/**
* 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
* 限制,则创建并返回新连接
*
* @param name 在属性文件中定义的连接池名字
* @return Connection 可用连接或null
*/
public Connection getConnection(String name) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
return pool.getConnection();
}
return null;
}

/**
* 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
* 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
*
* @param name 连接池名字
* @param time 以毫秒计的等待时间
* @return Connection 可用连接或null
*/
public Connection getConnection(String name, long time) {
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null) {
return pool.getConnection(time);
}
return null;
}

public int getClient(){
return clients;
}

/**
* 关闭所有连接,撤销驱动程序的注册
*/
public synchronized void release() {
// 等待直到最后一个客户程序调用
if (--clients != 0) {
return;
}
Enumeration allPools = pools.elements();
while (allPools.hasMoreElements()) {
DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
pool.release();
}
Enumeration allDrivers = drivers.elements();
while (allDrivers.hasMoreElements()) {
Driver driver = (Driver) allDrivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
log("撤销JDBC驱动程序 " + driver.getClass().getName()+"的注册");
}
catch (SQLException e) {
log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());
}
}
}

/**
* 根据指定属性创建连接池实例.
*
* @param props 连接池属性
*/
private void createPools(Properties props) {
Enumeration propNames = props.propertyNames();
while (propNames.hasMoreElements()) {
String name = (String) propNames.nextElement();
if (name.endsWith(".url")) {
String poolName = name.substring(0, name.lastIndexOf("."));
String url = props.getProperty(poolName + ".url");
if (url == null) {
log("没有为连接池" + poolName + "指定URL");
continue;
}
String user = props.getProperty(poolName + ".user");
String password = props.getProperty(poolName + ".password");
String maxconn = props.getProperty(poolName + ".maxconn", "0");
int max;
try {
max = Integer.valueOf(maxconn).intValue();
}
catch (NumberFormatException e) {
log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName);
max = 0;
}
DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max);
pools.put(poolName, pool);
log("成功创建连接池" + poolName);
}
}
}

/**
* 读取属性完成初始化
*/
private void init() {
InputStream is = getClass().getResourceAsStream("/db.properties");
Properties dbProps = new Properties();
try {
dbProps.load(is);
System.out.println("读取数据成功!");
}
catch (Exception e) {
System.err.println("不能读取属性文件. " +"请确保db.properties在CLASSPATH指定的路径中");
return;
}
String logFile = dbProps.getProperty("logfile", "DBManager.log");
System.out.println("日志文件存放位置:"+logFile);
try {
log = new PrintWriter(new FileWriter(logFile, true), true);
}catch (IOException e) {
System.err.println("无法打开日志文件: " + logFile);
log = new PrintWriter(System.err);
}
loadDrivers(dbProps);
createPools(dbProps);
}

/**
* 装载和注册所有JDBC驱动程序
*
* @param props 属性
*/
private void loadDrivers(Properties props) {
String driverClasses = props.getProperty("drivers");
StringTokenizer st = new StringTokenizer(driverClasses);
while (st.hasMoreElements()) {
String driverClassName = st.nextToken().trim();
try {
Driver driver = (Driver)Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
log("成功注册JDBC驱动程序" + driverClassName);
}
catch (Exception e) {
log("无法注册JDBC驱动程序: " + driverClassName + ", 错误: " + e);
}
}
}

/**
* 将文本信息写入日志文件
*/
private void log(String msg) {
log.println(new Date().toLocaleString() + ": " + msg);
}

/**
* 将文本信息与异常写入日志文件
*/
private  void log(Throwable e, String msg) {
log.println(new Date() + ": " + msg);
e.printStackTrace(log);
}

/**
* 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
* 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
*/
class DBConnectionPool {
private int checkedOut;
private Vector freeConnections = new Vector();
private int maxConn;
private String name;
private String password;
private String URL;
private String user;

/**
* 创建新的连接池
*
* @param name 连接池名字
* @param URL 数据库的JDBC URL
* @param user 数据库帐号,或 null
* @param password 密码,或 null
* @param maxConn 此连接池允许建立的最大连接数
*/
public DBConnectionPool(String name, String URL, String user, String password,int maxConn) {
this.name = name;
this.URL = URL;
this.user = user;
this.password = password;
this.maxConn = maxConn;
}

/**
* 将不再使用的连接返回给连接池
*
* @param con 客户程序释放的连接
*/
public synchronized void freeConnection(Connection con) {
// 将指定连接加入到向量末尾
freeConnections.addElement(con);
checkedOut--;
notifyAll();
}

/**
* 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
* 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
* 然后递归调用自己以尝试新的可用连接.
*/
public synchronized Connection getConnection() {
Connection con = null;
if (freeConnections.size() &gt; 0) {
// 获取向量中第一个可用连接
con = (Connection) freeConnections.firstElement();
freeConnections.removeElementAt(0);
if (con.isClosed()) {
log("从连接池" + name+"删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
}
}
else if (maxConn == 0 || checkedOut &lt; maxConn) {
con = newConnection();
}
if (con != null) {
checkedOut++;
}
return con;
}

/**
* 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
* 参见前一个getConnection()方法.
*
* @param timeout 以毫秒计的等待时间限制
*/
public synchronized Connection getConnection(long timeout) {
long startTime = new Date().getTime();
Connection con;
while ((con = getConnection()) == null) {
try {
wait(timeout);
}
catch (InterruptedException e) {}
if ((new Date().getTime() - startTime) &gt;= timeout) {
// wait()返回的原因是超时
return null;
}
}
return con;
}

/**
* 关闭所有连接
*/
public synchronized void release() {
Enumeration allConnections = freeConnections.elements();
while (allConnections.hasMoreElements()) {
Connection con = (Connection) allConnections.nextElement();
try {
con.close();
log("关闭连接池" + name+"中的一个连接");
}
catch (SQLException e) {
log(e, "无法关闭连接池" + name+"中的连接");
}
}
freeConnections.removeAllElements();
}

/**
* 创建新的连接
*/
private Connection newConnection() {
Connection con = null;
try {
if (user == null) {
con = (Connection) DriverManager.getConnection(URL);
}
else {
con = (Connection) DriverManager.getConnection(URL, user, password);
}
log("连接池" + name+"创建一个新的连接");
}
catch (SQLException e) {
log(e, "无法创建下列URL的连接: " + URL);
return null;
}
return con;
}
}
}
</pre>
 
<p><span style="color: #ff0000;">init()方法在创建属性对象并读取db.properties文件之后,就开始检查logfile属性。如果属性文件中没有指定日志文件,则默认为当前目录下的DBConnectionManager.log文件。如日志文件无法使用,则向System.err输出日志记录。</span></p>
<p><span style="color: #ff0000;"><br>装载和注册所有在drivers属性中指定的JDBC驱动程序由loadDrivers()方法实现。该方法先用StringTokenizer将drivers属性值分割为对应于驱动程序名称的字符串,然后依次装载这些类并创建其实例,最后在 DriverManager中注册</span></p>
<p><span style="color: #ff0000;"><br>该实例并把它加入到一个私有的向量drivers。向量drivers将用于关闭服务时从DriverManager取消所有JDBC 驱动程序的注册。</span></p>
<p><span style="color: #ff0000;"><br>init()方法的最后一个任务是调用私有方法createPools()创建连接池对象。createPools()方法先创建所有属性名字的枚举对象(即Enumeration对象,该对象可以想象为一个元素系列,逐次调用其nextElement()方法将顺序返回各元素),然后在其中搜索名字以“.url”结尾的属性。对于每一个符合条件的属性,先提取其连接池名字部分,进而读取所有属于该连接池的属性,最后创建连接池对象并把它保存在实例变量pools中。散列表(Hashtable类 )pools实现连接池名字到连接池对象之间的映射,此处以连接池名字为键,连接池对象为值。</span></p>
<p><span style="color: #ff0000;"><br>为便于客户程序从指定连接池获得可用连接或将连接返回给连接池,类DBConnectionManager提供了方法getConnection()和freeConnection()。所有这些方法都要求在参数中指定连接池名字,具体的连接获取或返回操作则调用对应的连接池对象完成。</span></p>
<p><span style="color: #ff0000;"><br>为实现连接池的安全关闭,DBConnectionManager提供了方法release()。在上面我们已经提到,所有DBConnectionManager的客户程序都应该调用静态方法getInstance()以获得该管理器的引用,此调用将增加客户程序计数。</span></p>
<p><span style="color: #ff0000;"><br>客户程序在关闭时调用release()可以递减该计数。当最后一个客户程序调用release(),递减后的引用计数为0,就可以调用各个连接池的release()方法关闭所有连接了。管理类release()方法最后的任务是撤销所有JDBC驱动程序的注册。</span></p>
<p> </p>
<p> </p>
<p> </p>
<p>Servlet使用连接池示例</p>
<p> </p>
<p> </p>
<p> </p>
<p>Servlet API所定义的Servlet生命周期类如:<br><br>1) 创建并初始化Servlet(init()方法)。<br>2) 响应客户程序的服务请求(service()方法)。<br>3) Servlet终止运行,释放所有资源(destroy()方法)。<br><br>本例演示连接池应用,上述关键步骤中的相关操作为:<br><br>1) 在init(),用实例变量connMgr 保存调用DBManager.getInstance()所返回的引用。<br>2) 在service(),调用getConnection(),执行数据库操作,用freeConnection()将连接返回给连接池。<br>3) 在destroy(),调用release()关闭所有连接,释放所有资源。</p>
<p> </p>
<p> </p>
<p> </p>
<p>示例程序清单如下:</p>
<p> </p>
<p> </p>
<pre name="code" class="java">import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TestServlet extends HttpServlet {
private DBManager connMgr;

public void init(ServletConfig conf) throws ServletException {
super.init(conf);
connMgr = DBManager.getInstance();
}

public void service(HttpServletRequest req, HttpServletResponse res)
throws IOException {

res.setContentType("text/html");
PrintWriter out = res.getWriter();
Connection con = connMgr.getConnection("idb");
if (con == null) {
out.println("不能获取数据库连接.");
return;
}
ResultSet rs = null;
ResultSetMetaData md = null;
Statement stmt = null;
try {
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT * FROM EMPLOYEE");
md = rs.getMetaData();
out.println("&lt;H1&gt;职工数据&lt;/H1&gt;");
while (rs.next()) {
out.println("&lt;BR&gt;");
for (int i = 1; i &lt; md.getColumnCount(); i++) {
out.print(rs.getString(i) + ", ");
}
}
stmt.close();
rs.close();
}
catch (SQLException e) {
e.printStackTrace(out);
}
connMgr.freeConnection("idb", con);
}

public void destroy() {
connMgr.release();
super.destroy();
}
}</pre>
 
<p> </p>
<p> </p>
<p>测试下吧O(∩_∩)O</p>
5 楼 nishijia 2009-07-30  
设计的不太好   考虑的太少
觉得用 LinkedList来代替Map 比较好  还是需要用线程
4 楼 srdrm 2009-07-29  
自己实现连接池一般应该实现 DataSource 接口,以及用一个实现Connection接口的类, 来包装原始 Connection 实例.

针对你这个类, 说一点, 好像 Connection 的Map 处理有点问题, key是connection , value是Boolean, value 是表示连接是否正被使用吧, 好像处理上有点问题.

然后还有个, 如果 DriverManager.getConnection 产生了异常, 你这里隐藏了这个异常, 当然就返回null了, 这个异常应该抛出来, 方法声明为throws sqlexception. 你现在返回null实际上表示底层的驱动已无法支持这么多的Connection了, 除非你让申请线程等待有连接返回到池中,这样设计就又复杂了. 但不能返回一个null的Connection
3 楼 nishijia 2009-07-29  
zxmsdyz 写道
unsid 写道
两个建议:
1、getConnection中,如果池内没有连接则新建一个,新建的又不归池管,那连接池还有什么意义?应该判断如果池内连接全部占用则判断池连接数是否达到最大,如果最大了则阻塞wait,直到有人释放了连接才notify;如果没到,则新建一个连接放在池内并返回

2、release用来释放连接非常不好,因为很多习惯conn.close()写,导致了连接池中连接收不回来,应该创建连接的时候用Proxy重写Connection的close方法,在其中将true改成false


第二个明白了,第一条怎么做的呢,能否详细讲讲


	private static class ConnectionHandler implements InvocationHandler {
		/**
		 * 连接是否可用。
		 */
		private boolean enabled;

		/**
		 * 连接(Connection)对象。
		 */
		private Connection conn;

		/**
		 * 构造器。
		 * 
		 * @param conn
		 * 连接(Connection)对象。
		 * 
		 */
		public ConnectionHandler(Connection conn) {
			this.conn = conn;
			enabled = true;
		}

		/**
		 * 代理方法,特别对于close方法进行了处理。
		 */
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			// 该连接管理者是否不可用?
			if (!enabled)
				// 抛出空指针异常
				throw new NullPointerException();
			// 是否调用了close方法?
			if (method.getName() == "close") {
		           if (xx条件) {  
                             // 关闭连接。  
                               conn.close();  
                           }                  
                        }

			// 正常调用连接的各种方法。
			return method.invoke(conn, args);
		}

	}


是这样吗?  conn的isClose属性是protected  没法直接调
2 楼 zxmsdyz 2009-07-29  
unsid 写道
两个建议:
1、getConnection中,如果池内没有连接则新建一个,新建的又不归池管,那连接池还有什么意义?应该判断如果池内连接全部占用则判断池连接数是否达到最大,如果最大了则阻塞wait,直到有人释放了连接才notify;如果没到,则新建一个连接放在池内并返回

2、release用来释放连接非常不好,因为很多习惯conn.close()写,导致了连接池中连接收不回来,应该创建连接的时候用Proxy重写Connection的close方法,在其中将true改成false


第二个明白了,第一条怎么做的呢,能否详细讲讲
1 楼 unsid 2009-07-29  
两个建议:
1、getConnection中,如果池内没有连接则新建一个,新建的又不归池管,那连接池还有什么意义?应该判断如果池内连接全部占用则判断池连接数是否达到最大,如果最大了则阻塞wait,直到有人释放了连接才notify;如果没到,则新建一个连接放在池内并返回

2、release用来释放连接非常不好,因为很多习惯conn.close()写,导致了连接池中连接收不回来,应该创建连接的时候用Proxy重写Connection的close方法,在其中将true改成false

相关推荐

    自己写的连接池

    自己写的java 连接池

    自己写的数据库连接池(java)

    在给定的标题“自己写的数据库连接池(java)”中,我们可以推测这是一个用户自定义的数据库连接池实现,可能是为了学习或实践目的。描述提到的“XML版读取属性文件”和“普通的”,暗示了两种不同的配置方式,一种是...

    一个比较好手写连接池

    在IT行业中,数据库连接池是优化数据库访问性能和资源管理的重要技术。标题提到的“一个比较好手写连接池”指的是一个由个人或团队独立...开发者可以根据自己的需求定制连接池的特性和行为,从而更好地适应项目的需求。

    自己写的一个简单的连接池

    这里,我们讨论的是一个自定义实现的简单连接池。 连接池的核心功能通常包括以下几点: 1. **初始化与配置**:连接池在启动时需要根据预先设定的参数(如最大连接数、最小连接数、超时时间等)进行初始化。这些...

    java手写数据库连接池

    数据库连接池是Java应用程序中非常重要的一个组件,它在提高应用性能、节省系统资源方面起着关键作用。本文将深入探讨如何使用Java手写数据库连接池,并基于maven进行项目构建。我们将分析四个核心类的功能,以及...

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

    自定义连接池的基本思想是维护一个连接池,当应用需要连接时从池中获取,用完后归还。核心部分包括连接的创建、管理和回收,以及连接池的大小控制策略。实现自定义连接池需要考虑线程安全、连接有效性检测、异常处理...

    关于如何手写连接池的资料

    本资料将详细介绍如何手写一个简单的连接池实现,以帮助理解连接池的工作原理。 在Java中,我们通常使用`java.sql.Connection`接口来代表数据库连接。一个连接池的实现主要包括以下几个核心功能: 1. **初始化配置...

    JAVA写的一个连接池

    JAVA学习中,自己学着写的一个连接池.

    java手写连接池

    Java手写连接池是一个编程实践,它涉及到数据库管理和优化,主要目标是提高数据库访问的效率和资源利用率。在Java中,连接池是一个管理数据库连接的系统,它预先创建一定数量的数据库连接,当应用程序需要时可以立即...

    自己写的数据库连接池

    数据库连接池是应用程序管理数据库连接的一种机制,它在多个并发请求之间共享数据库连接,从而减少了创建和销毁数据库连接的开销。在这个项目中,你使用Java实现了一个自定义的数据库连接池,应用了代理模式来优化...

    java写的数据库连接池

    数据库连接池是Java开发中非常重要的一个概念,它在处理大量并发访问数据库的应用场景中扮演着关键角色。本文将深入探讨数据库连接池的工作原理、重要性以及如何在Java中实现一个简单的连接池。 首先,数据库连接池...

    DELPHI7写的ADO连接池

    DELPHI7编写的ADO连接池是数据库应用开发中的一个重要技术,它主要用于管理和优化数据库连接,提高系统性能并防止可能出现的死锁问题。在多用户同时访问SQL数据库时,如果没有有效的连接管理,可能会出现资源竞争,...

    C#编写的数据库连接池

    然而,如果你想自定义更复杂的连接池逻辑,例如根据需求动态调整连接池大小,那么就需要自己编写代码来实现。 描述中提到的“DBHelper2.0”可能是一个自定义的数据库操作类库,它封装了连接池的创建、管理和数据库...

    poolman 数据库连接池+源码例子,自己写的代码

    Poolman是一个自定义实现的数据库连接池,通过管理和复用数据库连接,避免了频繁创建和销毁连接带来的开销。在这个项目中,你将找到Poolman 2.0.4版本的源码以及相关的示例代码,这将帮助你深入理解数据库连接池的...

    Qt 多线程连接数据库——数据库连接池

    * 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字 * 支持多线程,保证获取到的连接一定是没有被其他线程正在使用 * 按需创建连接,可以创建多个连接,可以控制连接的数量 * 连接...

    ftp连接池实例

    写ftp连接池的目的就是合理的利用资源,本文的目的是在初始的时候,创建10个Ftp连接,放到一个队列中去,当多个用户同时去下载ftp上的文件的时候,就会从队列中取,若当前的队列中存在着空闲的连接,就获取该ftp的...

    自己写的数据库连接池(全)

    这里提到的"自己写的数据库连接池"是一个自定义实现,提供了全面的功能和详细的方法,旨在帮助开发者理解和实践数据库连接池的工作原理。 数据库连接池的基本原理是预先创建并维护一定数量的数据库连接,当应用程序...

    手写数据库连接池(java)连sqlserver

    发现csdn上的连接池都是配设xml的,就手写了一份数据库连接池(java),连接sqlserver,里面一共两个java代码,Conn类包含了Connection和标志位,myconnection包含了数据库连接池的使用:获取连接,增加连接,释放...

    glassfish建立连接池

    GlassFish 是一个功能强大且流行的Java EE 应用服务器,它提供了强大的连接池机制,使得应用程序可以高效地访问数据库。下面,我们将介绍如何在 GlassFish 管理员界面中配置连接池,特别是使用 Oracle 数据库为例。 ...

    java数据库连接池源码及使用示例

    本资源包含了一个名为`jdbcPool`的手写数据库连接池源码以及一个`jdbcPoolTest`的调用示例,支持Oracle和MySQL数据库。 首先,我们来看`jdbcPool`连接池的实现。在Java中,连接池通常由以下几个核心组件组成: 1. ...

Global site tag (gtag.js) - Google Analytics