can you look at my connection pool if it is a possible way to implement it?
public class ConnectionPool {
private static List<DBConnection> pool = null;
private static int available = 0;
private ConnectionPool() {}
public static DBConnection getConnection() {
if (pool == null) {
pool = new ArrayList<DBConnection>();
for (int i = 0; i < 3; i++) {
try {
pool.add(new DBConnection());
available++;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
if (pool.size() > 0) {
available--;
return pool.remove(available);
} else {
return null;
}
}
public static void returnConnection(DBConnection c) {
pool.add(c);
available++;
}
}
I'm using only one array and the client should ask the connection pool for a connection use it and then return it to the connection pool.
Connection connection = ConnectionPool.getConnection();
connection.execute("insert into users values('"+user.getUsername()+"', '"+user.getPassword()+"', '"+user.getGroup()+"', '"+banned+"', '"+broker+admin+sharehodler+company+"')");
ConnectionPool.returnConnection(connection);
connection = null;
Please I need feedback on this implementation. Thank you
There are some points that make this implementation very problematic.
ConnectionPool
.I'm sure there's more to point out, but unless these are fixed, there's no use in continuing.
One big problem with your pool implementation is that you pass the naked connection to the callers of the pool. This means that someone can obtain a connection from your pool, close it, and then return it to the pool. This is bad .
The normal way around this problem is to wrap the return connection objects using delegation, and make them ignore calls to the close method (or even better, make close() safely return the underlying connection to the pool).
Other major issues:
All in all, you should reuse an existing connection pool implementation rather than writing your own. These days, many type 4 drivers have their own connection pools included right within the driver.
Some thoughts:
AFAIK,
your getConnection()
method need to be changed to in order to retrieve Connection
object only.
Preparing connection and pooling should be taken away from the getConnection() method and added in such a way that when ConnectionPool
class is loaded first time.
Also you need to handle some other attributes as well like connection timeout
, purging
etc in order to make it work for all scenarios.
Make it thread safe as well.
Other members have already suggested lots of things. I have some model implementation, thought of sharing it for new visitors. Here is code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
abstract class ObjectPool<T> {
private ConcurrentLinkedQueue<T> pool;
ScheduledExecutorService executorService;
ObjectPool(int minObjects) {
pool = new ConcurrentLinkedQueue<T>();
for (int i = 0; i < minObjects; i++) {
pool.add(createObject());
}
}
ObjectPool(final int minObjects, final int maxSize, final long interval){
pool = new ConcurrentLinkedQueue<T>();
for (int i = 0; i < minObjects; i++) {
pool.add(createObject());
}
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable(){
public void run() {
int size = pool.size();
while(size > maxSize){
pool.remove();
}
Iterator i = pool.iterator();
while(i.hasNext()){
T t = (T) i.next();
if(checkExpiry(t)){
System.out.println("Expiry existed...");
i.remove();
}
}
while(pool.size() < minObjects){
System.out.println("Adding more objects to pool");
pool.add(createObject());
}
}
}, interval, interval, TimeUnit.MILLISECONDS);
}
public T borrowObject() {
if (pool.peek() == null)
return createObject();
return pool.remove();
}
public void addObject(T obj) {
if (obj == null)
return;
pool.add(obj);
}
public abstract T createObject();
public abstract boolean checkExpiry(T t);
}
class MultithreadQuery extends Thread{
private ObjectPool<Connection> pool;
private int threadNo;
String query;
MultithreadQuery(ObjectPool<Connection> pool,int threadNo, String query){
this.pool = pool;
this.threadNo = threadNo;
this.query = query;
}
@Override
public void run(){
Connection con = pool.borrowObject();
Statement stmt;
try {
stmt = con.createStatement();
System.out.println("Query started for thread->"+ threadNo);
ResultSet rs=stmt.executeQuery(query);
while(rs.next())
System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getString(3));
System.out.println("closing connection....");
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pool.addObject(con);
System.out.println("Query ended for thread->"+ threadNo);
}
}
public class ObjectPoolPatternDemo {
ObjectPool<Connection> pool;
public void setUp(){
pool = new ObjectPool<Connection>(4, 10, 1) {
@Override
public Connection createObject() {
Connection con;
try {
con = DriverManager.getConnection("URL","Username","Password");
return con;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public boolean checkExpiry(Connection conn) {
boolean expiryFlag = false;
try {
if(conn.isClosed())
expiryFlag = true;
} catch (SQLException e) {
e.printStackTrace();
}
return expiryFlag;
}
};
}
public static void main(String[] args) throws SQLException {
ObjectPoolPatternDemo oppd = new ObjectPoolPatternDemo();
oppd.setUp();
ExecutorService es = Executors.newFixedThreadPool(4);
String query = "select * from TABLE";
es.execute(new MultithreadQuery(oppd.pool,1,query));
es.execute(new MultithreadQuery(oppd.pool,2,query));
es.execute(new MultithreadQuery(oppd.pool,3,query));
es.execute(new MultithreadQuery(oppd.pool,4,query));
es.execute(new MultithreadQuery(oppd.pool,5,query));
es.execute(new MultithreadQuery(oppd.pool,6,query));
es.shutdown();
try {
es.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("finally completed...");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.