您的位置:首页 > 数据库

通过一个简单的数据库连接池分析一下“等待超时模式”

2018-03-12 01:33 387 查看
场景描述:开发人员经常会遇到这样的方法调用场景:调用一个方法时等待一段时间(一般来说是给定一个时间段),如果该方法能够在给定的时间段之内得到结果, 那么将结果立刻返回, 反之,超时返回默认结果。

·等待持续时间: REMAINING=T。
·超时时间: FUTURE=now+T。
这时仅需要wait(REMAINING)即可, 在wait(REMAINING)返回之后会将执行:
REMAINING=FUTURE–now。 如果REMAINING小于等于0, 表示已经超时, 直接退出, 否则将
继续执行wait(REMAINING)。

一个简单的数据库连接池(只是简单展示一下这个模式,就不写怎么用了)public class ConnectionPool {
//Connection只是一个接口,具体实现是由数据库厂商决定的
private LinkedList<Connection> pool = new LinkedList<Connection>() ;

public ConnectionPool(int initialSize) {
if (initialSize > 0) {
for (int i = 0; i < initialSize; i++) {
pool. addLast(ConnectionDriver. createConnection()) ;
}
}
}

public void releaseConnection(Connection connection) {
if (connection ! = null) {
synchronized (pool) {
// 连接释放后需要进行通知, 这样其他消费者能够感知到连接池中已经归还了一个连接
pool.addLast(connection) ;
pool.notifyAll() ;
}
}
}

// 在mills内无法获取到连接, 将会返回null
public Connection fetchConnection(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;
}
}
}
}在这一段代码中
while (pool.isEmpty() && remaining > 0) {
     pool.wait(remaining) ;
     remaining = future - System.currentTimeMillis() ;
}
这里的wait()方法我是这么理解的,在wait方法执行后,一直经过了remaining毫秒后还未有其他线程唤醒他时,这个线程相当于自己唤醒了,但是这个自己唤醒自己还是有一个条件,就是他必须获取pool的锁,否则就算超时时间到了他还是被阻塞的,不能继续往下执行,所以这个线程最终的超时时间不一定是刚好的remaining毫秒。当然这里加个超时时间还是有用的,毕竟不会永远阻塞自己
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐