`
nmj1987
  • 浏览: 30311 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
文章分类
社区版块
存档分类
最新评论

对数据库连接池的一些修改

阅读更多

上次写的连接池一旦得不到连接就返回null,个人觉得很不合理。稍微改了一下,增加了等待时间。另外,连接池的容量改成了缓慢增加,而不是一下子就翻一倍。

ConnectionPool.java

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.Vector;

public class ConnectionPool {

    private Vector<Connection> pool;

    private String url;

    private String username;

    private String password;

    private String driverClassName;
    /** 
     * 请求连接的等待时间限制
     */
    private long timeout;
    /** 
     * 连接池的大小,也就是连接池中有多少个数据库连接。
     */
    private int poolSize;
    
    private int poolSizeMax;

    private static ConnectionPool instance = new ConnectionPool();

    private ConnectionManager connectionManager;
    /** 
     * 私有的构造方法,禁止外部创建本类的对象,要想获得本类的对象,通过<code>getIstance</code>方法。
     * 使用了设计模式中的单子模式。
     */
    private ConnectionPool() {
        init();
    }

    /** 
     * 连接池初始化方法,读取属性文件的内容 建立连接池中的初始连接
     */
    private void init() {
        pool = new Vector<Connection>();
        readConfig();
        initConnection(poolSize);  //初始化最小的线程数
        connectionManager = new ConnectionManager(pool,poolSize);
        connectionManager.start();
    }

    /** 
     * 返回连接到连接池中
     */
    public synchronized void release(Connection conn) {
        pool.add(conn);
        notifyAll();//通知所有等待连接的线程
    }

    /** 
     * 关闭连接池中的所有数据库连接
     */
    public synchronized void closePool() {
        for (int i = 0; i < pool.size(); i++) {
            try {
                ((Connection) pool.get(i)).close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            pool.remove(i);
        }
    }

    /** 
     * 返回当前连接池的一个对象
     */
    public static ConnectionPool getInstance() {
        return instance;
    }

    /** 
     * 返回连接池中的一个数据库连接 
     */
    public synchronized Connection getConnection() {
    	Connection conn =null;
		try {
			conn = getConnection(timeout);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
		
    }
    
    /** 
     * 返回连接池中的一个数据库连接
     * @throws SQLException 
     */
    private Connection getConnection(long timeout) throws SQLException  {
    	long startTime = System.currentTimeMillis();
    	long remaining = timeout;
    	Connection conn = null;
    	while((conn=getPooledConnection()) == null){
    		try {
				wait(remaining);//没有可用的链接,线程等待,直到超时或其它线程调用了notifyAll
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			remaining = timeout - (System.currentTimeMillis() - startTime);
    		if(remaining<=0){  //超时则抛出异常
    			throw new SQLException("getConnection() timeout");
    		}
    	}
    	//如果无异常抛出,则获得了一个连接,现测试该连接是否可用
    	if(!isConnectionOK(conn)){
    		return getConnection(remaining);
    	}
		return conn;
	}

	/** 
     * 测试连接是否真正是可用的
     */
    private boolean isConnectionOK(Connection conn) {
		Statement stmt = null;
		try{
			if(!conn.isClosed()){
				stmt = conn.createStatement();
				stmt.close();
			}
			else{
				return false;
			}
		}
		catch(SQLException e){
			if(stmt!=null){
				try{
					stmt.close();
				}
				catch(SQLException se){		
				}	
			}
			return false;
		}
		return true;
	}

	/** 
     * 在连接池中创建初始设置的的数据库连接
     */
    private void initConnection(int size) {
        Connection conn = null;
        for (int i = 0; i < size; i++) {

            try {
                Class.forName(driverClassName);
                conn = java.sql.DriverManager.getConnection(url, username, password);
                pool.add(conn);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }
    }
    
    private Connection getPooledConnection(){
    	Connection conn = null;
    	if(pool.size()>0){
    		conn = pool.remove(0);
    	}
    	else if(poolSize<poolSizeMax){
    		conn = newConnection();
    	}
		return conn;
    }
    /** 
     * 获得新连接
     */
    private Connection newConnection(){
    	Connection conn = null ;
    	try {
            Class.forName(driverClassName);
            conn = java.sql.DriverManager.getConnection(url, username, password);
            pool.add(conn);
            poolSize++;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    	return conn;
    }

    /** 
     * 读取设置连接池的属性文件
     */
    private void readConfig() {
        try {
            String path = System.getProperty("user.dir") + "\\dbpool.properties";
            FileInputStream is = new FileInputStream(path);
            Properties props = new Properties();
            props.load(is);
            this.driverClassName = props.getProperty("driverClassName");
            this.username = props.getProperty("username");
            this.password = props.getProperty("password");
            this.url = props.getProperty("url");
            this.poolSize = Integer.parseInt(props.getProperty("poolSizeMin"));
            this.poolSizeMax = Integer.parseInt(props.getProperty("poolSizeMax"));
            this.timeout = Integer.parseInt(props.getProperty("timeout"));
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("读取属性文件出错. ");        
        }
    }
}

 ConnectionManager.java

import java.sql.Connection;
import java.util.Vector;

public class ConnectionManager extends Thread{
	
	/*连接池最小的链接数量*/
	public static int MIN_SIZE = 3;
	
    private Vector<Connection> pool;
    
    private int poolSize;
	
	public ConnectionManager(Vector<Connection> pool,int poolSize)
	{
		this.pool = pool;
		this.poolSize = poolSize;
	}
	
	public void run() 
	{
		while(pool.size()>MIN_SIZE)  
		{
			pool.setSize(pool.size()-1);
			poolSize--;
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 

dbpool.properties

driverClassName=com.microsoft.jdbc.sqlserver.SQLServerDriver
username=sa
password=123456
url=jdbc:microsoft:sqlserver://localhost:1433/estore
poolSizeMax=10
poolSizeMin=3
timeout=5000

 

1
0
分享到:
评论
3 楼 wh8766 2009-03-08  
=,=
没被看到...
2 楼 nmj1987 2009-03-08  
public synchronized void release(Connection conn) { 
        pool.add(conn); 
        notifyAll();//通知所有等待连接的线程 
    }
用完connection后调用release方法,就又回到了vector里。
1 楼 wh8766 2009-03-08  
一个小问题~
这里的connection是一次性使用的么?看这里没有写回收connection的方法
比如把remove掉的连接通过一个回收再次添加到vector里

相关推荐

    JAVA数据库连接池

    Java数据库连接池是Java开发中一个非常重要的技术,它主要用于管理数据库连接,提高数据库操作...通过深入学习《最新修改java数据库连接池原理与应用(陈迁小组)》这份资料,你将对数据库连接池有更全面、深入的理解。

    数据库连接池查询

    ### 数据库连接池查询知识点详解 ...综上所述,通过对数据库连接池的有效管理和监控,可以有效提升数据库系统的稳定性和性能。希望以上内容能够帮助大家更好地理解和应对数据库连接管理方面的问题。

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

    MySQL数据库连接池是提高应用程序性能的一种重要技术,它允许开发者管理多个数据库连接并高效地复用这些连接,而不是每次需要时都创建新的连接。在C#编程中,我们可以使用自定义的连接池或者第三方库如ADO.NET的...

    JSP数据库连接池连接实例

    在IT行业中,数据库连接池是优化应用程序性能的关键技术之一,特别是在使用Java服务器页面(JSP)进行Web开发时。数据库连接池允许程序高效地管理与数据库的连接,减少了创建和销毁连接的开销,提高了系统资源利用率...

    几种数据库连接池详细配置

    通过以上对Apache DBCP和C3P0的配置参数的详细解析,我们可以看到,虽然这两种数据库连接池的实现方式不同,但它们都提供了丰富的配置项来满足不同的应用场景需求。合理设置这些参数,可以有效提升系统的性能和稳定...

    数据库连接池管理策略

    数据库连接池管理策略是优化数据库应用性能的关键环节。在软件开发中,特别是涉及到与数据库交互的应用,连接池的使用能够显著提升系统效率。本文将详细解释数据库连接池的工作原理、优缺点以及如何进行管理和配置。...

    XML解析和数据库连接池

    上传的"upload.ppt"可能包含关于XML解析、JDBC和数据库连接池的详细讲解,可能涵盖了如何配置和使用这些技术,以及它们在实际项目中的应用场景和最佳实践。如果需要深入学习,建议查看该文件内容以获取更具体的信息...

    普元平台使用阿里druid数据库连接池的配置说明20171010.docx

    4. 修改 tomcat/conf 下的 context.xml 配置文件,添加 Druid 数据库连接池的配置信息。在 context.xml 文件中添加 Druid 数据库连接池的配置信息,如数据源名称、数据库连接 URL、用户名、密码等信息。 Druid ...

    Java各数据库连接池配置介绍

    Java数据库连接池是管理数据库连接的一种机制,它可以有效地复用数据库连接,避免每次数据库操作时创建和销毁连接的开销,从而提高了应用的性能。在Java中,有多种数据库连接池实现,包括C3P0、DBCP和Proxool等。 *...

    JSP 数据库连接池技术

    在Java Web开发中,JSP(JavaServer Pages)是一种用于创建动态网页的技术,而数据库连接池是优化数据库访问性能和管理资源的关键组件。本篇将深入探讨JSP中如何运用数据库连接池技术,以及它的重要性。 数据库连接...

    tomcat数据库连接池的使用

    在Java开发中,Tomcat作为一款广泛使用的应用服务器,提供了对数据库连接池的支持,使得应用程序可以高效、便捷地管理数据库连接。本文将详细介绍如何在Tomcat中配置和使用数据库连接池,以及相关的知识点。 首先,...

    数据库连接池(应用代理模式实现,并提供管理接口)

    数据库连接池是应用程序中用于管理和复用数据库连接的机制,它可以显著提高系统性能,减少数据库资源的频繁创建和销毁。在本项目中,你将看到一个自定义的数据库连接池实现,它运用了代理模式以及面向接口编程的概念...

    c++数据库连接池ccc

    目前写的是postgresql的数据库的连接池,如果是别的数据库也可以在代码上面做修改,只需要更改前面的database和参数,采用的是c++面向对象的连接池,能够自动开辟和释放,默认开辟5个链接对象,可以根据自己的需求...

    一个连接多种数据库的连接池封装包

    数据库连接池是数据库管理中的重要组成部分,它优化了数据库资源的使用,提高了系统性能。本文将详细介绍一个连接多种数据库的连接池封装包,包括其功能、实现方式以及如何使用。 标题中的“一个连接多种数据库的...

    连接池管理连接oracle数据库

    这是用连接池技术管理连接oracle数据库的工具类代码,如果想连接MySQL,直接修改配置文件即可。

    java oracle 数据库 连接池 小例子

    数据库连接池在初始化时会创建一定数量的数据库连接,这些连接在应用程序需要时可以被复用,而不是每次请求时都创建新的连接,从而减少了创建和销毁连接的开销。C3P0作为连接池实现之一,提供了很多配置参数,例如...

    Tomcat5的数据库连接池配置Tomcat5的数据库连接池配置

    ### Tomcat5的数据库连接池配置详解 #### 引言 在Java Web开发中,数据库连接池是一项关键的技术,能够显著提升应用性能和资源利用效率。对于Tomcat5这一历史较为悠久但依然在某些场景中活跃的服务器软件,正确...

    Tomcat服务器配置及数据库连接池配置(个人整理版)

    ### Tomcat服务器配置及数据库连接池配置详解 #### 一、Tomcat服务器配置与环境搭建 ##### 1. JDK安装与配置 - **系统环境**:Windows 2003 Server SP3。 - **JDK路径设置**: - `JAVA_HOME` 设置为 `C:\JDK`。 ...

    数据库连接池配置终极指南

    通过对Tomcat的部署流程和数据库连接池配置的详细介绍,我们可以看到使用现代化的开发工具和技术可以极大地简化开发工作,提升开发效率。在实际操作过程中,遵循最佳实践,利用可用的工具和服务,可以使配置过程变得...

Global site tag (gtag.js) - Google Analytics