浏览 2045 次
锁定老帖子 主题:java数据库连接池实现
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-02-05
.package cc.vicp.eden.plug; . .import java.sql.*; .import java.util.*; .import java.lang.reflect.*; . ./** . * 连接池类。 . * . * @version 0.13 . * @author Eden . * . */ .public abstract class ConnectionPool { . /** . * 连接池。 . */ . private static final LinkedList<ConnectionHandler> pool; . . /** . * 最小连接数量,最大连接数量。 . */ . private static final int minConn, maxConn; . . /** . * 当前连接数量。 . */ . private static int curConn; . . /** . * 数据库的基本参数。 . */ . private static final String className, url, user, password; . /** . * 静态初始化。 . */ . static { . // 初始化池。 . pool = new LinkedList<ConnectionHandler>(); . // 初始化基本连接信息。 . minConn = 70; . maxConn = 100; . curConn = 0; . . className = "com.mysql.jdbc.Driver"; . url = "jdbc:mysql://localhost/jforum"; . user = "root"; . password = "n8NrCwfj"; . . // 加载数据库驱动。 . try { . Class.forName(className); . } catch (ClassNotFoundException e) { . e.printStackTrace(); . } . } . . /** . * 得到一个连接。 . * . * @return 连接(Connection)对象。 . * @throws SQLException . */ . public static Connection getConnection() throws SQLException { . // 当前已经使用的连接是否达到或超出最大连接数? . if (curConn >= maxConn) . // 抛出连接用尽异常。 . throw new ConnectExhaustException(); . Connection conn = null; . synchronized (pool) { . // 连接池内的连接是否有可用连接? . if (pool.size() > 0) { . ConnectionHandler handler = null; . // 得到一个连接管理者,并从连接池中移除。 . handler = pool.removeFirst(); . // 将该连接管理者设为可用。 . handler.enabled = true; . // 创建一个连接管理者(以代理方式创建)。 . conn = (Connection) Proxy.newProxyInstance(handler.conn . .getClass().getClassLoader(), handler.conn.getClass() . .getInterfaces(), handler); . } else { . // 创建一个链接。 . conn = DriverManager.getConnection(url, user, password); . // 创建一个连接管理者(以代理方式创建)。 . conn = (Connection) Proxy.newProxyInstance(conn.getClass() . .getClassLoader(), conn.getClass().getInterfaces(), . new ConnectionHandler(conn)); . } . // 当前已使用连接数增加1。 . curConn++; . System.out.println(Thread.currentThread().getName() . + " : getConnection" + "\ncurConn:" + curConn + "\npool:" . + pool.size() + "\n"); . } . // 以连接的方式返回连接管理者对象 . return conn; . . } . . /** . * 连接管理者类。 . * . * @author Eden . * . */ . 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") { . synchronized (pool) { . // 已使用连接数是否超出了最小连接数。 . if (curConn > minConn) { . // 关闭连接。 . conn.close(); . } else { . // 将连接管理者设为不可用。 . this.enabled = false; . // 将该连接返回连接池中。 . pool.add(this); . } . // 当前已使用连接数减少1。 . curConn--; . System.out.println(Thread.currentThread().getName() + " : " . + method.getName() + "\ncurConn:" + curConn . + "\npool:" + pool.size() + "\n"); . } . // 返回一个空值。 . return null; . } . . // 正常调用连接的各种方法。 . return method.invoke(conn, args); . } . . } . . /** . * 连接用尽异常类。 . * . * @author Eden . * . */ . private static final class ConnectExhaustException extends RuntimeException { . /** . * 版本序列号。 . */ . private static final long serialVersionUID = 0L; . } . . // ///////////////////////////////////////////////////////// . /* 其后部分为测试代码。 */ . private static final Object lock = new Object(); . . public static void main(String[] args) throws SQLException, . InterruptedException { . // 产生100个等待线程。 . for (int i = 0; i < 100; i++) { . new Monitor("Monitor - " + i); . } . // 提供产生100个等待线程的等待时间(1秒)。 . Thread.sleep(1000); . synchronized (cc.vicp.eden.plug.Monitor.lock) { . // 同时唤醒所有线程。 . cc.vicp.eden.plug.Monitor.lock.notifyAll(); . } . // 等待线程执行(5秒)。 . Thread.sleep(5000); . // 答应最终剩余连接数以及连接池中的可用连接数。 . System.out.println("\n\n\nfinal curConn : " + curConn + "\nfinal pool : " + pool.size()); . } .} . ./** . * 测试类。 . * . * @author Eden . * . */ .class Monitor extends Thread { . . public static final Object lock = new Object(); . . private Connection conn; . private static final Random random = new Random(); . . . public Monitor(String name) { . this.setName(name); . this.setPriority(Thread.MAX_PRIORITY); . this.start(); . } . . @Override . public void run() { . synchronized (lock) { . try { . System.out.println(this.getName() + " is ready!"); . lock.wait(); . } catch (InterruptedException e) { . e.printStackTrace(); . } . } . . try { . this.conn = ConnectionPool.getConnection(); . } catch (SQLException e) { . e.printStackTrace(); . } . . /*try { . Thread.sleep(Math.abs(random.nextInt() % 3) + 1); . } catch (InterruptedException e) { . e.printStackTrace(); . }*/ . . try { . conn.close(); . } catch (SQLException e) { . e.printStackTrace(); . } . } .}
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |