一,概述

本人认为在开发过程中,需要挑战更高的阶段和更优的代码,虽然在真正开发工作中,代码质量和按时交付项目功能相比总是无足轻重。但是个人认为开发是一条任重而道远的路。现在本人在网上找到一个自定义连接池的代码,分享给大家。无论是线程池还是db连接池,他们都有一个共同的特征:资源复用,在普通的场景中,我们使用一个连接,它的生命周期可能是这样的:

一个连接,从创建完毕到销毁,期间只被使用一次,当周期结束之后,另外的调用者仍然需要这个连接去做事,就要重复去经历这种生命周期。因为创建和销毁都是需要对应服务消耗时间以及系统资源去处理的,这样不仅浪费了大量的系统资源,而且导致业务响应过程中都要花费部分时间去重复的创建和销毁,得不偿失,而连接池便被赋予了解决这种问题的使命!

二,连接池简要需求

和原始周期相比,连接池多了一下特性:

1,创建并不是真的创建,而是从池子中选出空闲连接。

2,销毁并不是真的销毁,而是将使用中的连接放回池中。

3,真正的创建和销毁由线程池的特性机制来决定。

4,保存连接的容器是必不可少的,另外,该容器也要支持连接的添加和移除功能,并保证线程安全。

5,我们需要因为要对连接的销毁做逻辑调整,我们需要重写它的close以及isClosed方法。

6,我们需要有个入口对连接池做管理,例如回收空闲连接,连接池不仅仅只是对Connection生命周期的控制,还应该加入一些特色,例如初始连接数,最大连接数,最小连接数、最大空闲时长以及获取连接的等待时长,这些我们也简单支持一下。

容器连接池的选型:

1,要保证线程安全,我们可以将目标瞄准在JUC包下的神通们,设我们想要的容器为X,那么X不仅需要满足基本的增删改查功能,而且也要提供获取超时功能,这是为了保证当池内长时间没有空闲连接时不会导致业务阻塞,即刻熔断。另外,x需要满足双向操作,这是为了连接池可以识别出饱和的空闲连接,方便回收操作。

综上所述,LinkedBlockingDeque是最合适的选择,它使用InterruptibleReentrantLock来保证线程安全,使用Condition来做获取元素的阻塞,另外支持双向操作。

另外,我们可以将连接池分为3个类型:

工作池:存在正在被使用的连接。

空闲池:存在空闲连接。

回收池:已经被回收(物理关闭)的连接。

其中,工作池和回收池大可不必用双向队列,或许用单向队列或者set都可以代替之:

private LinkedBlockingQueueworkQueue;private LinkedBlockingQueueidleQueue;private LinkedBlockingQueue freezeQueue;

Connection 的装饰

连接池的输出是Connection,它代表着一个db连接,上游服务使用它做完操作后,会直接调用它的close方法来释放连接,而我们必须做的是在调用者无感知的情况下改变它的关闭逻辑,当调用close的方法时,我们将它放回空闲队列中,保证其的可复用性!

因此,我们需要对原来的Connection做装饰,其做法很简单,但是很累,这里新建一个类来实现Connection接口,通过重写所有的方法来实现一个“可编辑”的Connection,我们称之为Connection的装饰者:

public class HoneycombConnectionDecorator implementsConnection{protectedConnection connection;protectedHoneycombConnectionDecorator(Connection connection) {this.connection =connection;

}

此处省略对方法实现的三百行代码...

}

之后,我们需要新建一个自己的Connection来继承这个装饰者,并重写相应的方法:

public class HoneycombConnection extends HoneycombConnectionDecorator implementsHoneycombConnectionSwitcher{

@Overridepublic void close() { dosome things }

@Overridepublic boolean isClosed() throws SQLException { dosome things }

省略...

}

DataSource的重写

DataSource是JDK为了更好的统合和管理数据源而定义出的一个规范,获取连接的入口,方便我们在这一层更好的扩展数据源(例如增加特殊属性),使我们的连接池的功能更加丰富,我们需要实现一个自己的DataSource:

public class HoneycombWrapperDatasource implementsDataSource{protectedHoneycombDatasourceConfig config;

省略其它方法的实现...

@Overridepublic Connection getConnection() throwsSQLException {returnDriverManager.getConnection(config.getUrl(), config.getUser(), config.getPassword());

}

@Overridepublic Connection getConnection(String username, String password) throwsSQLException {returnDriverManager.getConnection(config.getUrl(), username, password);

}

省略其它方法的实现...

}

我们完成了对数据源的实现,但是这里获取连接的方式是物理创建,我们需要满足池化的目的,需要重写HoneycombWrapperDatasource中的连接获取逻辑,做法是创建一个新的类对父类方法重写:

public class HoneycombDataSource extendsHoneycombWrapperDatasource{privateHoneycombConnectionPool pool;

@Overridepublic Connection getConnection() throwsSQLException {

这里实现从pool中取出连接的逻辑

}

省略...

}

特性扩展

在当前结构体系下,我们的连接池逐渐浮现出了雏形,但远远不够的是,我们需要在此结构下可以做自由的扩展,使连接池对连接的控制更加灵活,因此我们可以引入特性这个概念,它允许我们在其内部访问连接池,并对连接池做一系列的扩展操作:

public abstract classAbstractFeature{public abstract voiddoing(HoneycombConnectionPool pool);

}

AbstractFeature抽象父类需要实现doing方法,我们可以在方法内部实现对连接池的控制,其中一个典型的例子就是对池中空闲连接左回收:

public class CleanerFeature extendsAbstractFeature{

@Overridepublic voiddoing(HoneycombConnectionPool pool) {

这里做空闲连接的回收

}

}

三,落实计划

java 自己实现连接池_JAVA自定义连接池原理设计(一)相关推荐

  1. jdbc 连接池 java_JDBC自定义连接池过程详解

    这篇文章主要介绍了JDBC自定义连接池过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 开发中,"获得连接"和" ...

  2. 数据库连接池之自定义连接池(mysql)

    数据库连接池之自定义连接池(mysql) 上一篇博文是"基于mysql的JDBC的增删改查的封装":点击可查看 今天本仙在昨天JDBC封装增删改查的基础上实现自定义的数据库连接池: ...

  3. java dbcp连接池_Java——DBCP连接池

    连接池 实际开发中"获得连接"或"释放资源"是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection.这样 ...

  4. java redis释放连接池_Java 使用连接池操作redis

    构建连接池对象JedisPool JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379); ...

  5. mysql odbc连接池_Java Mysql连接池配置和案例分析--超时异常和处理

    前言: 最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测 ...

  6. java自定义线程_Java自定义线程池详解

    自定义线程池的核心:ThreadPoolExecutor 为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制,其中在java.util.concurrent ...

  7. java 多线程池_Java ThreadPoolExecutor线程池 同时执行50个线程

    最近项目上有个需求,需要从FTP服务器中下载大批量的数据文件,然后解析该数据文件进行入库,数据库为oracle,最后在通过web工程,以报表和图表的形式进行展现. 这些批量的数据文件为纯文本文件,每天 ...

  8. 【Java线程】“打工人”初识线程池及自定义线程池实战

    目录 理论 原理 线程池创建 工作流程图 拒绝策略 参数设置 四种线程池 实战 理论 聊一下为什么要使用线程池? 程序的运行本质,就是通过使用系统资源(CPU.内存.网络.磁盘等等)来完成信息的处理, ...

  9. java定时线程池_java 定时器线程池(ScheduledThreadPoolExecutor)的实现

    前言 定时器线程池提供了定时执行任务的能力,即可以延迟执行,可以周期性执行.但定时器线程池也还是线程池,最底层实现还是ThreadPoolExecutor,可以参考我的另外一篇文章多线程–精通Thre ...

  10. java运行时读取注解_Java自定义注解和运行时靠反射获取注解

    转:1.Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型.该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰 ...

最新文章

  1. 【requests】Python轻松爬取FTP
  2. 简单的协议应用-代理模式
  3. Linux - 命令
  4. python字典items返回什么_Python 字典items返回列表,iteritems返回迭代器
  5. java quartz 2.2.3_java – Spring 3 Quartz 2错误
  6. 手把手教你建立用户画像和用户场景
  7. JavaScript数组快速入门
  8. Microsoft Office Visio 2007 下载
  9. 数据库设计以及PD数据导入数据库
  10. 《凤凰项目》--读书笔记
  11. 高通量测序领域常用名词解释
  12. 2021国防科技大学计算机学院无军籍考研经验贴
  13. 一个程序员是如何蜕变为投资人的?
  14. ctfhub Git泄露学习
  15. 【功能安全】【ISO26262】支持过程
  16. 360类redis存储服务Pika的安装和使用
  17. English trip V1 - 10.Family Ties 家庭关系 Teacher:Emily Key: Possessive s (所有格 s)
  18. 计算机科学导论(6):操作系统
  19. UE4 /UE5 PC/安卓优化
  20. 笔记 vue3 如何引入第三方字体

热门文章

  1. 国产linux聊天软件,程序员的全平台聊天软件:Rocket.Chat
  2. 软件测试理论思维导图
  3. python经济统计_Python商务与经济统计学-方差分析
  4. 项目范围管理__范围管理计划 与 范围说明书
  5. 西门子PID完整程序西门子PLC 1200和多台G120西门子变频器Modbud RTU通讯
  6. 一键生成数据库文档(持续更新)
  7. wav转换mp3简单图文教程
  8. 图像处理之matlab的取整函数round、ceil、floor和fix
  9. matlab绘制小人奔跑动图,如何做奔跑的小人运动规律-动画初学者入门教程
  10. dinic算法 c 语言,网络流Dinic算法详解及模板