⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionpool.java

📁 基于Jabber协议的即时消息服务器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/** * $RCSfile$ * $Revision: 3189 $ * $Date: 2005-12-11 19:38:08 -0800 (Sun, 11 Dec 2005) $ * * Copyright (C) 2004 Jive Software. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution. */package org.jivesoftware.database;import org.jivesoftware.util.ClassUtils;import org.jivesoftware.util.Log;import org.jivesoftware.util.JiveGlobals;import java.io.IOException;import java.sql.*;import java.util.*;/** * Database connection pool. * * @author Jive Software */public class ConnectionPool implements Runnable {    private String driver;    private String serverURL;    private String username;    private String password;    private int minCon;    private int maxCon;    private int conTimeout;    private boolean mysqlUseUnicode;    private Thread houseKeeper;    private boolean shutdownStarted = false;    private int conCount = 0;    private int waitingForCon = 0;    private Connection[] cons;    private ConnectionWrapper[] wrappers;    private Object waitLock = new Object();    private Object conCountLock = new Object();    public ConnectionPool(String driver, String serverURL, String username,                          String password, int minCon, int maxCon,                          double conTimeout, boolean mysqlUseUnicode) throws IOException {        this.driver = driver;        this.serverURL = serverURL;        this.username = username;        this.password = password;        this.minCon = minCon;        this.maxCon = maxCon;        // Setting the timeout to 3 hours        this.conTimeout = (int)(conTimeout * 1000 * 60 * 60 * 3); // convert to milliseconds        this.mysqlUseUnicode = mysqlUseUnicode;        if (driver == null) {            Log.error("JDBC driver value is null.");        }        try {            ClassUtils.forName(driver);            DriverManager.getDriver(serverURL);        }        catch (ClassNotFoundException e) {            Log.error("Could not load JDBC driver class: " + driver);        }        catch (SQLException e) {            Log.error("Error starting connection pool.", e);        }        // Setup pool, open minimum number of connections        wrappers = new ConnectionWrapper[maxCon];        cons = new Connection[maxCon];        boolean success = false;        int maxTry = 3;        for (int i = 0; i < maxTry; i++) {            try {                for (int j = 0; j < minCon; j++) {                    createCon(j);                    conCount++;                }                success = true;                break;            }            catch (SQLException e) {                // close any open connections                for (int j = 0; j < minCon; j++) {                    if (cons[j] != null) {                        try {                            cons[j].close();                            cons[j] = null;                            wrappers[j] = null;                            conCount--;                        }                        catch (SQLException e1) { /* ignore */                        }                    }                }                // let admin know that there was a problem                Log.error("Failed to create new connections on startup. " +                        "Attempt " + i + " of " + maxTry, e);                try {                    Thread.sleep(10000);                }                catch (InterruptedException e1) { /* ignore */                }            }        }        if (!success) {            throw new IOException();        }        // Start the background housekeeping thread        houseKeeper = new Thread(this);        houseKeeper.setDaemon(true);        houseKeeper.start();    }    public Connection getConnection() throws SQLException {        // if we're shutting down, don't create any connections        if (shutdownStarted) {            return null;        }        // Check to see if there are any connections available. If not, then enter wait-based        // retry loop        ConnectionWrapper con = getCon();        if (con != null) {            synchronized (con) {                con.checkedout = true;                con.lockTime = System.currentTimeMillis();            }            return con;        }        else {            synchronized (waitLock) {                try {                    waitingForCon++;                    while (true) {                        con = getCon();                        if (con != null) {                            --waitingForCon;                            synchronized (con) {                                con.checkedout = true;                                con.lockTime = System.currentTimeMillis();                            }                            return con;                        }                        else {                            waitLock.wait();                        }                    }                }                catch (InterruptedException ex) {                    --waitingForCon;                    waitLock.notifyAll();                    throw new SQLException("Interrupted while waiting for connection to " +                            "become available.");                }            }        }    }    public void freeConnection() {        synchronized (waitLock) {            if (waitingForCon > 0) {                waitLock.notifyAll();            }        }    }    public void destroy() throws SQLException {        // set shutdown flag        shutdownStarted = true;        // shut down the background housekeeping thread        houseKeeper.interrupt();        // wait 1/2 second for housekeeper to die        try {            houseKeeper.join(500);        }        catch (InterruptedException e) { /* ignore */        }        // check to see if there's any currently open connections to close        for (int i = 0; i < conCount; i++) {            ConnectionWrapper wrapper = wrappers[i];            // null means that the connection hasn't been initialized, which will only occur            // if the current index is greater than the current connection count            if (wrapper == null) {                break;            }            // if it's currently checked out, wait 1/2 second then close it anyways            if (wrapper.checkedout) {                try {                    Thread.sleep(500);                }                catch (InterruptedException e) {/* ignore */                }                if (wrapper.checkedout) {                    Log.info("Forcefully closing connection " + i);                }            }            cons[i].close();            cons[i] = null;            wrappers[i] = null;        }    }    public int getSize() {        return conCount;    }    /**     * Housekeeping thread. This thread runs every 30 seconds and checks connections for the     * following conditions:<BR>     * <p/>     * <ul>     * <li>Connection has been open too long - it'll be closed and another connection created.     * <li>Connection hasn't been used for 30 seconds and the number of open connections is     * greater than the minimum number of connections. The connection will be closed. This     * is done so that the pool can shrink back to the minimum number of connections if the     * pool isn't being used extensively.     * <li>Unable to create a statement with the connection - it'll be reset.     * </ul>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -