Java——基于等待通知超时模式的连接池
2018-01-18 21:14
453 查看
连接池对象:
/**
* \* Created: liuhuichao
* \* Date: 2018/1/15
* \* Time: 下午1:35
* \* Description:连接池类-负责创建,持有连接
* \
*/
public class ConnectionPool {
private LinkedList<Connection> pool=new LinkedList<>();//从链表首部获取连接,从尾部回收连接
/**
* 数据库连接池构造函数
* @param initSize 连接池初始化大小
*/
public ConnectionPool(int initSize){
if(initSize>0){
for(int i=0;i<initSize;i++){
pool.addLast(ConnectionDriver.createConnection());
}
}
}
/**
* 获取连接
* @param mils 等待时间,即等待多久获取不到连接就超时
* @return
* @throws InterruptedException
*/
public Connection fetchConnection(long mils) throws InterruptedException{
synchronized (pool){
//当传入的参数为负数时候,不使用等待超时,直接是一直等待到获取到通知为止
if(mils<=0){
while (pool.isEmpty()){
pool.wait();
}
return pool.removeFirst();
}else{//超时等待。。。
long future=System.currentTimeMillis()+mils;
long remaining=mils;
while (pool.isEmpty()&&remaining>0){//使用等待超时模型
pool.wait(remaining);
remaining=future-System.currentTimeMillis();
}
/**注意,超时之后,说明一直没有获取到通知,此时,返回的连接为null**/
Connection result=null;
if(!pool.isEmpty()){
result=pool.removeFirst();
}
return result;
}
}
}
/**
* 释放连接
* @param connection
*/
public void releaseConnection(Connection connection){
if(connection!=null){
synchronized (pool){
//连接释放后需要进行通知,这样其他消费者能够感知到连接池中已经归还了一个连接
pool.addLast(connection);
pool.notifyAll();//通知所有等待的线程,可以获取连接了
}
}
}
}
获取连接:
/**
* \* Created: liuhuichao
* \* Date: 2018/1/15
* \* Time: 下午1:52
* \* Description:获取连接
* \
*/
public class ConnectionDriver {
/**
* 定义动态代理类
*/
static class ConnectionHandler 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;
}
}
/**
* 创建连接
* @return
*/
public static final Connection createConnection(){
return (Connection)Proxy.newProxyInstance(
ConnectionDriver.class.getClassLoader(),
new Class[]{Connection.class},
new ConnectionHandler());
}
}
测试连接:
/**
* \* Created: liuhuichao
* \* Date: 2018/1/17
* \* Time: 上午10:27
* \* Description:简单测试连接池
* \
*/
public class SimpleConnectionClientTest {
static ConnectionPool connectionPool=new ConnectionPool(10);
static AtomicInteger got=new AtomicInteger();
static AtomicInteger notGot=new AtomicInteger();
static int clientNum=100;//模拟客户端数量
static int waitConnectTimeout=100;//获取连接时候等待超时的时间
static int useConnectionTimeInterval=30;//客户端使用连接的时间
static CountDownLatch begin=new CountDownLatch(1);//用于控制线程同时开始的
static CountDownLatch finish=new CountDownLatch(clientNum);//用于保证main线程在所有客户端线程执行完之后可以获取执行结果
/**
* 测试代码
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
for (int i=0;i<clientNum;i++){
Thread client=new Thread(new GetConnectionTest(),"client-"+(i+1));
client.start();
}
begin.countDown();//客户端线程初始化完毕,可以开始了
finish.await();
System.out.println("got="+got);
System.out.println("notGot="+notGot);
}
/**
* 用于模拟客户端获取连接
*/
static class GetConnectionTest implements Runnable{
@Override
public void run() {
try {
begin.await();
Connection conn=connectionPool.fetchConnection(waitConnectTimeout);
if(conn==null){
notGot.incrementAndGet();
}else{
got.incrementAndGet();
Thread.sleep(useConnectionTimeInterval);//表示使用连接的过程
connectionPool.releaseConnection(conn);//表示使用连接完成之后释放连接的过程
}
finish.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
源码地址:https://github.com/SoledadVac/DataSourceConnectionPool
/**
* \* Created: liuhuichao
* \* Date: 2018/1/15
* \* Time: 下午1:35
* \* Description:连接池类-负责创建,持有连接
* \
*/
public class ConnectionPool {
private LinkedList<Connection> pool=new LinkedList<>();//从链表首部获取连接,从尾部回收连接
/**
* 数据库连接池构造函数
* @param initSize 连接池初始化大小
*/
public ConnectionPool(int initSize){
if(initSize>0){
for(int i=0;i<initSize;i++){
pool.addLast(ConnectionDriver.createConnection());
}
}
}
/**
* 获取连接
* @param mils 等待时间,即等待多久获取不到连接就超时
* @return
* @throws InterruptedException
*/
public Connection fetchConnection(long mils) throws InterruptedException{
synchronized (pool){
//当传入的参数为负数时候,不使用等待超时,直接是一直等待到获取到通知为止
if(mils<=0){
while (pool.isEmpty()){
pool.wait();
}
return pool.removeFirst();
}else{//超时等待。。。
long future=System.currentTimeMillis()+mils;
long remaining=mils;
while (pool.isEmpty()&&remaining>0){//使用等待超时模型
pool.wait(remaining);
remaining=future-System.currentTimeMillis();
}
/**注意,超时之后,说明一直没有获取到通知,此时,返回的连接为null**/
Connection result=null;
if(!pool.isEmpty()){
result=pool.removeFirst();
}
return result;
}
}
}
/**
* 释放连接
* @param connection
*/
public void releaseConnection(Connection connection){
if(connection!=null){
synchronized (pool){
//连接释放后需要进行通知,这样其他消费者能够感知到连接池中已经归还了一个连接
pool.addLast(connection);
pool.notifyAll();//通知所有等待的线程,可以获取连接了
}
}
}
}
获取连接:
/**
* \* Created: liuhuichao
* \* Date: 2018/1/15
* \* Time: 下午1:52
* \* Description:获取连接
* \
*/
public class ConnectionDriver {
/**
* 定义动态代理类
*/
static class ConnectionHandler 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;
}
}
/**
* 创建连接
* @return
*/
public static final Connection createConnection(){
return (Connection)Proxy.newProxyInstance(
ConnectionDriver.class.getClassLoader(),
new Class[]{Connection.class},
new ConnectionHandler());
}
}
测试连接:
/**
* \* Created: liuhuichao
* \* Date: 2018/1/17
* \* Time: 上午10:27
* \* Description:简单测试连接池
* \
*/
public class SimpleConnectionClientTest {
static ConnectionPool connectionPool=new ConnectionPool(10);
static AtomicInteger got=new AtomicInteger();
static AtomicInteger notGot=new AtomicInteger();
static int clientNum=100;//模拟客户端数量
static int waitConnectTimeout=100;//获取连接时候等待超时的时间
static int useConnectionTimeInterval=30;//客户端使用连接的时间
static CountDownLatch begin=new CountDownLatch(1);//用于控制线程同时开始的
static CountDownLatch finish=new CountDownLatch(clientNum);//用于保证main线程在所有客户端线程执行完之后可以获取执行结果
/**
* 测试代码
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
for (int i=0;i<clientNum;i++){
Thread client=new Thread(new GetConnectionTest(),"client-"+(i+1));
client.start();
}
begin.countDown();//客户端线程初始化完毕,可以开始了
finish.await();
System.out.println("got="+got);
System.out.println("notGot="+notGot);
}
/**
* 用于模拟客户端获取连接
*/
static class GetConnectionTest implements Runnable{
@Override
public void run() {
try {
begin.await();
Connection conn=connectionPool.fetchConnection(waitConnectTimeout);
if(conn==null){
notGot.incrementAndGet();
}else{
got.incrementAndGet();
Thread.sleep(useConnectionTimeInterval);//表示使用连接的过程
connectionPool.releaseConnection(conn);//表示使用连接完成之后释放连接的过程
}
finish.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
源码地址:https://github.com/SoledadVac/DataSourceConnectionPool
相关文章推荐
- Java 并发编程-再谈 AbstractQueuedSynchronizer 2:共享模式与基于 Condition 的等待 / 通知机制实现
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
- Java多线程编程-(18)-等待/通知模式接口Condition接口深入分析
- 再谈AbstractQueuedSynchronizer2:共享模式与基于Condition的等待/通知机制实现
- Java——等待,超时,通知模型
- 多线程编程中的等待/通知机制和等待超时模式
- 多线程编程中的等待/通知机制和等待超时模式
- 通过一个简单的数据库连接池分析一下“等待超时模式”
- Java多线程编程-(16)-等待/通知模式接口Condition接口深入分析
- Java多线程实例——等待超时模式
- java并发基础--等待通知模式
- Java中基于等待的调优方法详解(3)
- 基于Java的代理设计模式
- java线程安全之重入锁、锁与等待/通知、读写锁(十七)
- java线程之间的通信(等待/通知机制)
- Java线程与并发编程实践----等待通知(生产者消费者问题)线程
- Java基于装饰者模式实现的图片工具类实例【附demo源码下载】
- Java中基于等待的调优方法详解
- java多线程的等待和通知机制,两种实现方法
- 用于 Java 程序(J2SE, JSP/Servlet) 的可直接返回连接以及定时关闭超时连接的连接池程序