在常用的数据库连接池中就应用了等待超时模式,在代码示例中模拟从连接池中获取连接,使用和释放连接的过程。而客户端获取连接的过程被设定为等待超时的模式,
也就是在超时时间内如果无法获取到可用连接,将会返回一个null、设定连接池的数量为10个,然后通过条件客户端的线程数来模拟无法获取连接的场景。
public class ConnectionPool {
private LinkedList<Connection> pool = new LinkedList<Connection>();
private int initialSize = 10;
/**
* 初始化连接池
* @param initialSize
*/
public ConnectionPool(int initialSize) {
if(initialSize > 0) {
this.initialSize = initialSize;
}
for(int i=0;i<initialSize;i++){
pool.addLast(ConnectionDriver.createConnection());
}
}
/**
* 释放连接池中的连接
* @param connection
*/
public void releaseConnection(Connection connection){
if(connection != null){
synchronized (pool){
//连接放回连接池
pool.addLast(connection);
//连接放回连接池后,需要通知其他线程连接池中已经归还了一个连接,可以获取连接了
pool.notifyAll();
}
}
}
public Connection borrowConnection(long mills) throws InterruptedException{
synchronized (pool){
if(mills <= 0){
while (pool.isEmpty()){
pool.wait();
}
return pool.removeFirst();
}else{
long future = System.currentTimeMillis() + mills;
long remaining = mills;
while (pool.isEmpty() && remaining > 0){
pool.wait(remaining);
remaining = future - System.currentTimeMillis();
}
Connection result = null;
if(!pool.isEmpty()){
result = pool.removeFirst();
}
return result;
}
}
}
}
public class ConnectionDriver {
/**
* 创建一个Connection的代理,在commit时休眠100毫秒
* @return
*/
public static final Connection createConnection() {
return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[]{Connection.class}, new ConnectionHndler());
}
static class ConnectionHndler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("commit")) {
TimeUnit.MICROSECONDS.sleep(100);
}
return null;
}
}
}
public class ConnectionPoolTest {
static ConnectionPool pool = new ConnectionPool(10);
//保证所有的ConnectionThread线程能够同时开始
static CountDownLatch start = new CountDownLatch(1);
static CountDownLatch end;
public static void main(String[] args) throws Exception{
int threadCount = 1000;
end = new CountDownLatch(threadCount);
int count = 20;
AtomicInteger got = new AtomicInteger();
AtomicInteger notGot = new AtomicInteger();
for(int i=0;i<threadCount;i++){
Thread thread = new Thread(new ConnectionThread(count,got,notGot),"ConnectionThread");
thread.start();
}
start.countDown();
end.await();
System.out.println("total invoke:"+(threadCount*count));
System.out.println("got coonection:"+got);
System.out.println("not got connection:"+notGot);
}
static class ConnectionThread implements Runnable{
int count;
AtomicInteger got;
AtomicInteger notGot;
public ConnectionThread(int count, AtomicInteger got, AtomicInteger notGot) {
this.count = count;
this.got = got;
this.notGot = notGot;
}
@Override
public void run() {
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
while (count > 0){
try {
Connection connection = pool.borrowConnection(1000);
if(connection != null){
try {
connection.createStatement();
connection.commit();
}finally {
pool.releaseConnection(connection);
got.incrementAndGet();
}
}else{
notGot.incrementAndGet();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
count--;
}
}
end.countDown();
}
}
}
来源:CSDN
作者:one-fly
链接:https://blog.csdn.net/f529352479/article/details/51786281