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

📄 connectionpool.java

📁 数据库连接池在编写应用服务是经常需要用到的模块
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				// times to
				// find one.

				try {
					int loop = 0;
					int roundRobin = connLast + 1;
					if (roundRobin >= currConnections) {
						roundRobin = 0;

					}
					do {
						synchronized (connStatus) {
							if ((connStatus[roundRobin] < 1)
									&& (!connPool[roundRobin].isClosed())) {
								conn = connPool[roundRobin];
								connStatus[roundRobin] = 1;
								connLockTime[roundRobin] = System
										.currentTimeMillis();
								connLast = roundRobin;
								gotOne = true;
								break;
							} else {
								loop++;
								roundRobin++;
								if (roundRobin >= currConnections) {
									roundRobin = 0;
								}
							}
						}
					} while ((gotOne == false) && (loop < currConnections));
				} catch (SQLException e1) {
				}

				if (gotOne) {
					break; // break the outer loop
				} else {
					synchronized (this) { // Add new connections to the pool
						if (currConnections < maxconns) {
							try {
								createConn(currConnections);
								currConnections++;
							} catch (SQLException e) {
								System.out
										.println("Unable to create new connection: "
												+ String
														.valueOf(currConnections - 1));
								System.out.println("Exception : " + e);
							}
						} // if
					} // synchronized

					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
					}

					System.out
							.println("-----> Connections Exhausted!  Will wait and try "
									+ "again in outer loop "
									+ String.valueOf(outerloop));
				}
			} // End of try 10 times loop

		} else { // not available
			System.out
					.println("Unsuccessful getConnection() request during destroy()");
		} // End if(available)
		return conn;

	}

	/**
	 * Returns the local JDBC ID for a connection. if there's not the connection
	 * int the pool return -1
	 */
	public int idOfConnection(Connection conn) {
		int match;
		String tag;

		try {
			tag = conn.toString();
		} catch (NullPointerException e1) {
			tag = "none";
		}

		match = -1;

		for (int i = 0; i < currConnections; i++) {
			if (connID[i].equals(tag)) {
				match = i;
				break;
			}
		}
		return match;
	}

	/**
	 * Frees a connection. Replaces connection back into the main pool for
	 * reuse.
	 */
	public String freeConnection(Connection conn) {
		String res = "";

		int thisconn = idOfConnection(conn);
		if (thisconn >= 0) {
			connStatus[thisconn] = 0;
			res = "freed " + conn.toString();
			// log("Freed connection " + String.valueOf(thisconn) +
			// " normal exit: ");
		} else {
			System.out.println("----> Could not free connection!!!"
					+ "Try to close it directly");
			try {
				conn.close();
			} catch (SQLException e) {
			}
		}
		return res;
	}

	/**
	 * Returns the age of a connection -- the time since it was handed out to an
	 * application.
	 */
	public long getAge(Connection conn) { // Returns the age of the connection
		// in millisec.
		int thisconn = idOfConnection(conn);
		return System.currentTimeMillis() - connLockTime[thisconn];
	}

	/**
	 * Shuts down the housekeeping thread and closes all connections in the
	 * pool. Call this method from the destroy() method of the servlet.
	 * Multi-phase shutdown. having following sequence:
	 * <OL>
	 * <LI><code>getConnection()</code> will refuse to return connections.
	 * <LI>The housekeeping thread is shut down.<br>
	 * Up to the time of <code>millis</code> milliseconds after shutdown of
	 * the housekeeping thread, <code>freeConnection()</code> can still be
	 * called to return used connections.
	 * <LI>After <code>millis</code> milliseconds after the shutdown of the
	 * housekeeping thread, all connections in the pool are closed.
	 * <LI>If any connections were in use while being closed then a
	 * <code>SQLException</code> is thrown.
	 * <LI>The log is closed.
	 * </OL>
	 * <br>
	 * Call this method from a servlet destroy() method.
	 * 
	 * @param millis
	 *            the time to wait in milliseconds.
	 * @exception SQLException
	 *                if connections were in use after <code>millis</code>.
	 */
	public void destroy(int millis) throws SQLException {

		// Checking for invalid negative arguments is not necessary,
		// Thread.join() does this already in runner.join().

		// Stop issuing connections
		available = false;

		// Shut down the background housekeeping thread
		runner.interrupt();

		// Wait until the housekeeping thread has died.
		try {
			runner.join(millis);
		} catch (InterruptedException e) {
		} // ignore

		// The housekeeping thread could still be running
		// (e.g. if millis is too small). This case is ignored.
		// At worst, this method will throw an exception with the
		// clear indication that the timeout was too short.

		long startTime = System.currentTimeMillis();

		// Wait for freeConnection() to return any connections
		// that are still used at this time.
		int useCount;
		while ((useCount = getUseCount()) > 0
				&& System.currentTimeMillis() - startTime <= millis) {
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			} // ignore
		}

		// Close all connections, whether safe or not
		for (int i = 0; i < currConnections; i++) {
			try {
				connPool[i].close();
			} catch (SQLException e1) {
				System.out.println("Cannot close connections on Destroy");
			}
		}

		if (useCount > 0) {
			// bt-test successful
			String msg = "Unsafe shutdown: Had to close " + useCount
					+ " active DB connections after " + millis + "ms";
			System.out.println(msg);
			// Throwing following Exception is essential because servlet authors
			// are likely to have their own error logging requirements.
			throw new SQLException(msg);
		}

	} // End destroy()

	/**
	 * Less safe shutdown. Uses default timeout value. This method simply calls
	 * the <code>destroy()</code> method with a <code>millis</code> value of
	 * 10000 (10 seconds) and ignores <code>SQLException</code> thrown by that
	 * method.
	 * 
	 * @see #destroy(int)
	 */
	public void destroy() {
		try {
			destroy(10000);
		} catch (SQLException e) {
		}
	}

	/**
	 * Returns the number of connections in use.
	 */
	// This method could be reduced to return a counter that is
	// maintained by all methods that update connStatus.
	// However, it is more efficient to do it this way because:
	// Updating the counter would put an additional burden on the most
	// frequently used methods; in comparison, this method is
	// rarely used (although essential).
	public int getUseCount() {
		int useCount = 0;
		synchronized (connStatus) {
			for (int i = 0; i < currConnections; i++) {
				if (connStatus[i] > 0) { // In use
					useCount++;
				}
			}
		}
		return useCount;
	} // End getUseCount()

	/**
	 * Returns the number of connections in the dynamic pool.
	 */
	public int getSize() {
		return currConnections;
	} // End getSize()

	public static void main(String[] args) {
		String driver = "org.gjt.mm.mysql.Driver";
		String server = "jdbc:mysql://127.0.0.1/elearning?autoReconnect=true";
		String dbuser = "root";
		String dbpassword = "";
		int minconn = 5;
		int maxconn = 20;
		double maxconntime = 0.1D;
		try {
			ConnectionPool p = new ConnectionPool(driver, server, dbuser,
					dbpassword, minconn, maxconn, maxconntime);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

} // end class

⌨️ 快捷键说明

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