通过一个简单的数据库连接池分析一下“等待超时模式”
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毫秒。当然这里加个超时时间还是有用的,毕竟不会永远阻塞自己
·等待持续时间: 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毫秒。当然这里加个超时时间还是有用的,毕竟不会永远阻塞自己
相关文章推荐
- php和数据库结合的一个 简单的web实例 代码分析 (php初学者)
- 一个简单例子的设计模式分析
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 云课堂 Linux内核分析 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 简单分析一个通过 js 劫持进行案例
- 第一周:通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(原创)
- 通过汇编一个简单的C程序,分析汇编代码理解计算机工作原理
- 一个通过rms写成的小型数据库引擎,简单的数据库引擎
- 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过vmstat的简单分析数据库操作
- 通过动态代理(Proxy)实现的数据库连接池的创建连接与归还链接的操作的简单的实现流程
- lab1:通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- php和数据库结合的一个简单的web实例 代码分析 (php初学者)
- Ext源码分析源码分析之Ext的继承模式解说——第二节、一个简单的继承