数据库连接池(经测可用)

package com.software.db;

import java.sql.*;
import java.lang.reflect.*;
import java.util.*;
import java.io.*;

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;

    static {
        initDriver();
    }

    private SimpleConnetionPool() {
    }

    private static void initDriver() {
        Driver driver = null;
        try {
            driver = (Driver) Class.forName("com.mysql.jdbc.Driver")
                    .newInstance();
            installDriver(driver);
        } catch (Exception e) {
            System.out.println("驱动加载失败");
        }
    }

    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(), new Class[]{Connection.class}, 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;
    }

}


测试用例

package com.software.test;

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

import com.software.db.SimpleConnetionPool;

public class Test {
    public static void main(String[] args) {  
    SimpleConnetionPool.setUrl("jdbc:mysql://localhost:3306/softwaredb");  
    SimpleConnetionPool.setUser("root");  
    SimpleConnetionPool.setPassword("root");  
    Connection[] con=new Connection[15];  
    for (int i = 0; i < 15; i++) {
      con[i] = SimpleConnetionPool.getConnection();
    }
    for (int i = 0; i < con.length; i++) {
         System.out.println(con[i]);
    }
    try {
         for (int i = 0; i < 15; i++) {
              con[i].close();
            }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    Connection[] connection = new Connection[15];
    for (int i = 0; i < 15; i++) {
        connection[i] = SimpleConnetionPool.getConnection();
        System.out.println(connection[i]);
    }

}
}

测试结果

com.mysql.jdbc.JDBC4Connection@2c41d05d
com.mysql.jdbc.JDBC4Connection@14d6a05e
com.mysql.jdbc.JDBC4Connection@16ba8602
com.mysql.jdbc.JDBC4Connection@2fb3f8f6
com.mysql.jdbc.JDBC4Connection@509df6f1
com.mysql.jdbc.JDBC4Connection@32bf7190
com.mysql.jdbc.JDBC4Connection@36b8bef7
com.mysql.jdbc.JDBC4Connection@1b016632
com.mysql.jdbc.JDBC4Connection@78dc6a77
com.mysql.jdbc.JDBC4Connection@4ed1e89e
com.mysql.jdbc.JDBC4Connection@36ff057f
com.mysql.jdbc.JDBC4Connection@20c1f10e
com.mysql.jdbc.JDBC4Connection@1cb8deef
com.mysql.jdbc.JDBC4Connection@2d342ba4
com.mysql.jdbc.JDBC4Connection@3c1d332b
15
com.mysql.jdbc.JDBC4Connection@2c41d05d
com.mysql.jdbc.JDBC4Connection@14d6a05e
com.mysql.jdbc.JDBC4Connection@16ba8602
com.mysql.jdbc.JDBC4Connection@2fb3f8f6
com.mysql.jdbc.JDBC4Connection@509df6f1
com.mysql.jdbc.JDBC4Connection@32bf7190
com.mysql.jdbc.JDBC4Connection@36b8bef7
com.mysql.jdbc.JDBC4Connection@1b016632
com.mysql.jdbc.JDBC4Connection@78dc6a77
com.mysql.jdbc.JDBC4Connection@4ed1e89e
com.mysql.jdbc.JDBC4Connection@36ff057f
com.mysql.jdbc.JDBC4Connection@20c1f10e
com.mysql.jdbc.JDBC4Connection@1cb8deef
com.mysql.jdbc.JDBC4Connection@2d342ba4
com.mysql.jdbc.JDBC4Connection@3c1d332b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值