Java 连接池的工作原理
什么是连接?
连接,是我们的编程语言与数据库交互的一种方式。我们经常会听到这么一句话“数据库连接很昂贵“。
有人接受这种说法,却不知道它的真正含义。因此,下面我将解释它究竟是什么。[如果你已经知道了,你可以跳到它的工作原理部分]
创建连接的代码片段:
1
|
String connUrl = "jdbc:mysql://your.database.domain/yourDBname" ;
|
2
|
Class.forName( "com.mysql.jdbc.Driver" );
|
3
|
Connection con = DriverManager.getConnection (connUrl);
|
当我们创建了一个Connection对象,它在内部都执行了什么:
1.“DriverManager”检查并注册驱动程序,
2.“com.mysql.jdbc.Driver”就是我们注册了的驱动程序,它会在驱动程序类中调用“connect(url…)”方法。
3.com.mysql.jdbc.Driver的connect方法根据我们请求的“connUrl”,创建一个“Socket连接”,连接到IP为“your.database.domain”,默认端口3306的数据库。
4.创建的Socket连接将被用来查询我们指定的数据库,并最终让程序返回得到一个结果。
为什么昂贵?
现在让我们谈谈为什么说它“昂贵“。
如果创建Socket连接花费的时间比实际的执行查询的操作所花费的时间还要更长。
这就是我们所说的“数据库连接很昂贵”,因为连接资源数是1,它需要每次创建一个Socket连接来访问DB。
因此,我们将使用连接池。
连接池初始化时创建一定数量的连接,然后从连接池中重用连接,而不是每次创建一个新的。
怎样工作?
接下来我们来看看它是如何工作,以及如何管理或重用现有的连接。
我们使用的连接池供应者,它的内部有一个连接池管理器,当它被初始化:
1.它创建连接池的默认大小,比如指定创建5个连接对象,并把它存放在“可用”状态的任何集合或数组中。
例如,代码片段:
01
|
...
|
02
|
String connUrl = "jdbc:mysql://your.database.domain/yourDBname" ;
|
03
|
String driver = "com.mysql.jdbc.Driver" ;
|
04
|
private Map<java.sql.Connection, String> connectionPool = null ;
|
05
|
private void initPool() {
|
06
|
try {
|
07
|
connectionPool = new HashMap<java.sql.Connection, String>();
|
08
|
Class.forName(driver);
|
09
|
java.sql.Connection con = DriverManager.getConnection(dbUrl);
|
10
|
for ( int poolInd = poolSize; poolInd < 0 ; poolInd++) {
|
11
|
connectionPool.put(con, "AVAILABLE" );
|
12
|
}
|
13
|
}
|
14
|
...
|
2.当我们调用connectionProvider.getConnection(),然后它会从集合中获取一个连接,当然状态也会更改为“不可用”。
例如,代码片段:
01
|
...
|
02
|
public java.sql.Connection getConnection() throws ClassNotFoundException, SQLException
|
03
|
{
|
04
|
boolean isConnectionAvailable = true ;
|
05
|
for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) {
|
06
|
synchronized (entry) {
|
07
|
if (entry.getValue()== "AVAILABLE" ) {
|
08
|
entry.setValue( "NOTAVAILABLE" );
|
09
|
return (java.sql.Connection) entry.getKey();
|
10
|
}
|
11
|
isConnectionAvailable = false ;
|
12
|
}
|
13
|
}
|
14
|
if (!isConnectionAvailable) {
|
15
|
Class.forName(driver);
|
16
|
java.sql.Connection con = DriverManager.getConnection(connUrl);
|
17
|
connectionPool.put(con, "NOTAVAILABLE" );
|
18
|
return con;
|
19
|
}
|
20
|
return null ;
|
21
|
}
|
22
|
...
|
3.当我们关闭得到的连接,ConnectionProvider是不会真正关闭连接。相反,只是将状态更改为“AVAILABLE”。
例如,代码片段:
01
|
...
|
02
|
public void closeConnection(java.sql.Connection connection) throws ClassNotFoundException, SQLException {
|
03
|
for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) {
|
04
|
synchronized (entry) {
|
05
|
if (entry.getKey().equals(connection)) {
|
06
|
//Getting Back the conncetion to Pool
|
07
|
entry.setValue( "AVAILABLE" );
|
08
|
}
|
09
|
}
|
10
|
}
|
11
|
}
|
12
|
...
|
基本上连接池的实际工作原理就是这样,但也有可能使用不同的方式。
现在,你可能有一个问题,我们是否可以创造我们自己的连接池机制?
我的建议是使用已经存在的连接池机制,像C3P0,DBCP等。
Java 连接池的工作原理相关推荐
- mysql连接池的工作原理_连接池工作原理
连接池工作原理 连接池技术的核心思想是连接复用,通过建立一个数据库连接池以及一套连接使用.分配和管理策略,使得该连接池中的连接可以得到高效.安全的复用,避免了数据库连接频繁建立.关闭的开销. 连接池的 ...
- Java 线程池的工作原理
文章目录 概念 线程中的基本方法 线程复用 线程池的核心组件和核心类 线程池的工作原理 线程池中的workQueue任务队列 直接提交队列(SynchronousQueue) 有界任务队列(Array ...
- 全面解读Java线程池的工作原理
目录 一.为什么引入线程池技术? 二.Executor框架 2.1 Runnable.Callable与Future接口 2.2 Executor接口 2.2.1 Executor 2.2.2 Exe ...
- 彻底搞懂Java线程池的工作原理
一.线程池的基础知识 创建线程需要占用一定的操作系统资源,在高并发情况下,频繁的创建和销毁线程会大量消耗CPU和内存资源,对程序性能造成很大的影响.为了避免这一问题,Java提供了线程池(通过线程复用 ...
- java线程池的工作原理_JAVA线程池原理详解一
线程池的优点 1.线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用. 2.可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃. 线 ...
- Java线程池的工作原理与实现
简单介绍 创建线程有两种方式:继承Thread或实现Runnable.Thread实现了Runnable接口,提供了一个空的run()方法,所以不论是继承Thread还是实现Runnable,都要有自 ...
- java线程池的工作原理_Java 线程池的介绍以及工作原理
在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 2. 提高响应速度 ...
- java 连接池_初探数据库连接池
参考资料 数据库连接池学习笔记(一):原理介绍+常用连接池介绍 java数据库连接池实现原理 高性能数据库连接池的内幕 1. 为什么要使用连接池 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户 ...
- 数据库连接池的工作原理
对于共享资源,有一个很著名的设计模式:资源池(resource pool).该模式正是为解决资源频繁分配.释放所造成的问题.数据库连接池的基本思想就是为数据库连接建立一个"缓冲池" ...
最新文章
- Unity空间射击游戏开发教程
- 一段关于Unix与 Linux的暗黑史
- zcu102 hdmi example(一)
- 【Arduino】十秒挑战
- InnoDB 的辅助索引叶子节点为什么不直接保存的记录地址而要存主键键值
- cad怎么选择一个对象打散vba_CAD制图的二十四字秘诀!
- 阅读宋立恒《AI制胜:机器学习极简入门》第2章:机器学习中的数据预处理
- 【Shell教程】四----输入输出,条件判断,循环
- windows服务器新建管理员用户_用户和组管理
- 加入功能区buttonRibbon Button到SP2010特定列表或库
- 几何约束栏设置不包括_2011CAD考试样题
- 虚拟主机与云服务器的区别
- 如何在 Chrome 浏览器中安装印象笔记·剪藏插件
- 为什么电子计算机奏出美妙的交响,《延安,我把你追寻》教学设计
- ScrollMagic结合TweenMax的Demo
- 微信利用小号和大号的好友聊天(基于wxpy库)
- 三国杀移动版虎牢关模式神吕布技能是什么?
- 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一1.7 顺光拍摄展示更多细节...
- 二叉树的结点度表示法
- adams 两角之差测量 平动转动物体角度测量
热门文章
- VTK:图片之ImageOrientation
- Windows版Qt
- Qt Creator连接QNX设备
- OpenGL次表面散射
- C++const的作用与使用
- flink报错:Error: Static methods in interface require -target:jvm-1.8 已解决
- 4进程原语:fork()函数,getpid()函数和getppid()函数,getuid()函数,getgid()函数,vfork()
- Java与C#平台通信 WCF CXF SOAP
- java画虚线_java cansvas 画虚线要怎么设置?
- 经典卷积网络进阶--GoolgleNet详解