可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Need code to create the connection pool in java?
How does we make sure that connection pool doesn't return the same object which is already in use?
How happens if client closed the connection after taking it out from Connection pool?
Update 1:
I want to create this in Simple Java terms and want to see how it works in Multithreading Env. I mean which methods would be synchronized and which are not. Also will this class would be a public class? If yes then any one can access this class and reinitialize the connection pool?
Update 2:
I have some code as below. But i don't how "Closing a connection coming from a pool returns it to the pool, it doesn't close the connection physically."
Also i didn't understood this "Because if a connection has been borrowed from the pool and not returned yet, it's not "available" and can't be redistributed to another client of the pool."
import java.util.*;
import java.sql.*;
class ConnectionPoolManager
{
String databaseUrl = "jdbc:mysql://localhost:3306/myDatabase";
String userName = "userName";
String password = "userPass";
Vector connectionPool = new Vector();
public ConnectionPoolManager()
{
initialize();
}
public ConnectionPoolManager(
//String databaseName,
String databaseUrl,
String userName,
String password
)
{
this.databaseUrl = databaseUrl;
this.userName = userName;
this.password = password;
initialize();
}
private void initialize()
{
//Here we can initialize all the information that we need
initializeConnectionPool();
}
private void initializeConnectionPool()
{
while(!checkIfConnectionPoolIsFull())
{
System.out.println("Connection Pool is NOT full. Proceeding with adding new connections");
//Adding new connection instance until the pool is full
connectionPool.addElement(createNewConnectionForPool());
}
System.out.println("Connection Pool is full.");
}
private synchronized boolean checkIfConnectionPoolIsFull()
{
final int MAX_POOL_SIZE = 5;
//Check if the pool size
if(connectionPool.size() < 5)
{
return false;
}
return true;
}
//Creating a connection
private Connection createNewConnectionForPool()
{
Connection connection = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(databaseUrl, userName, password);
System.out.println("Connection: "+connection);
}
catch(SQLException sqle)
{
System.err.println("SQLException: "+sqle);
return null;
}
catch(ClassNotFoundException cnfe)
{
System.err.println("ClassNotFoundException: "+cnfe);
return null;
}
return connection;
}
public synchronized Connection getConnectionFromPool()
{
Connection connection = null;
//Check if there is a connection available. There are times when all the connections in the pool may be used up
if(connectionPool.size() > 0)
{
connection = (Connection) connectionPool.firstElement();
connectionPool.removeElementAt(0);
}
//Giving away the connection from the connection pool
return connection;
}
public synchronized void returnConnectionToPool(Connection connection)
{
//Adding the connection from the client back to the connection pool
connectionPool.addElement(connection);
}
public static void main(String args[])
{
ConnectionPoolManager ConnectionPoolManager = new ConnectionPoolManager();
}
}
回答1:
Need code to create the connection pool in java?
Not sure what the question is but don't create yet another connection pool, use an existing solution like C3P0, Apache DBCP, Proxool or BoneCP (a new player in that field). I would use C3P0.
How does we make sure that connection pool doesn't return the same object which is already in use?
Because if a connection has been borrowed from the pool and not returned yet, it's just not in the pool and can't be assigned to another client of the pool (resources are removed from the pool until they are returned).
How happens if client closed the connection after taking it out from Connection pool?
The connection a client gets from a pool is not really a java.sql.Connection
, it's a wrapper (a proxy) for a java.sql.Connection
that customizes the behavior of some methods. The close()
method is one of them and does not close the Connection
instance but returns it to the pool.
回答2:
Don't write your own. There are plenty of librarires out there that will do this for you that are open source and easy to use and will have solved all the problems you'll encounter trying to make it yourself.
Here is a simple example that uses Apache's Commons DBCP and Commons Pool:
First set up a DataSource.
javax.sql.DataSource source = new org.apache.commons.dbcp.BasicDataSource();
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUsername("username");
source.setPassword("password");
source.setUrl("jdbc:mysql://localhost:3306/myDatabase");
Once you have a DataSource, it is easy to get a connection from the pool.
java.sql.Connection connection = source.getConnection();
closing the connection will return it to the pool for you.
connection.close();
回答3:
I hope this source code helps
http://jagadeeshmanne.blogspot.in/2014/03/connection-pool-in-java-jdbc.html
Configuration.java
package com.jmanne.utils;
public class Configuration {
public String DB_USER_NAME ;
public String DB_PASSWORD ;
public String DB_URL;
public String DB_DRIVER;
public Integer DB_MAX_CONNECTIONS;
public Configuration(){
init();
}
private static Configuration configuration = new Configuration();
public static Configuration getInstance(){
return configuration;
}
private void init(){
DB_USER_NAME = "root"
DB_PASSWORD = "root"
DB_URL = "jdbc:mysql://localhost:3306/jmanne"
DB_DRIVER = "com.mysql.jdbc.Driver"
DB_MAX_CONNECTIONS = 5
}
}
JdbcConnectionPool.java
package com.jmanne.db;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.jmanne.utils.Configuration;
import com.mysql.jdbc.Connection;
public class JdbcConnectionPool {
List<connection> availableConnections = new ArrayList<connection>();
public JdbcConnectionPool()
{
initializeConnectionPool();
}
private void initializeConnectionPool()
{
while(!checkIfConnectionPoolIsFull())
{
availableConnections.add(createNewConnectionForPool());
}
}
private synchronized boolean checkIfConnectionPoolIsFull()
{
final int MAX_POOL_SIZE = Configuration.getInstance().DB_MAX_CONNECTIONS;
if(availableConnections.size() < MAX_POOL_SIZE)
{
return false;
}
return true;
}
//Creating a connection
private Connection createNewConnectionForPool()
{
Configuration config = Configuration.getInstance();
try {
Class.forName(config.DB_DRIVER);
Connection connection = (Connection) DriverManager.getConnection(
config.DB_URL, config.DB_USER_NAME, config.DB_PASSWORD);
return connection;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public synchronized Connection getConnectionFromPool()
{
Connection connection = null;
if(availableConnections.size() > 0)
{
connection = (Connection) availableConnections.get(0);
availableConnections.remove(0);
}
return connection;
}
public synchronized void returnConnectionToPool(Connection connection)
{
availableConnections.add(connection);
}
}
DataSource.java
package com.jmanne.db;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
public class DataSource {
static JdbcConnectionPool pool = new JdbcConnectionPool();
public static Connection getConnection() throws ClassNotFoundException, SQLException{
Connection connection = pool.getConnectionFromPool();
return connection;
}
public static void returnConnection(Connection connection) {
pool.returnConnectionToPool(connection);
}
}
回答4:
Just use Semaphores. Ideally what you should do is use CP3O
or DBCP
as your connection pool. Now you can throttle you connection based on Semaphore.
Every time you do Get
, you acquire and on every Release
you release it from Semaphore. More over semaphores are thread safe.
回答5:
Use one of the existing, e.g. Apache DBCP
The connections returned by the pool are often proxies which "ignore" the call to close()
from the application. When the connections are returned to the pool, they can be reused. Pools also close and reopen automatically if necessary.
回答6:
If your application runs on a server, then configure as Data Source, where server will take care of Pooling or else if a simple Java Client then use Apache DBCP(if to the database) or else use Apache Commons Pooling API
See here: Apache Commons
回答7:
One argument for rolling your own connpool is the configuration and additional jars that are avoided. I agree you need to enable the 3rd party interfaces so you can swap in a mature connpool, but having your own tiny solution can have its place. Self cleaning Vector with synchronized block and a conn wrapper with close() marking the conn as available works very well for servlet apps.