数据库连接池-连接的关闭内幕
下面我就想就上面的问题谈谈我的一点浅见,请大家批评指正。
大家都知道java语言是一种语言级的多线程机制的面向对象语言。比如说,java的基类object,它就有一些诸如wati(),notify(),notifyall()等线程控制的方法。如果大家学习过操作系统的化,我想应该知道线程存在同步和异步的问题,解决的方法很多,其中就有“信号量机制”实现线程的同步,java的这种同步机制与操作系统大同小异。同步机制是一个比较复杂的问题,如果感兴趣可以找一本操作系统的书看看。
下面简单介绍一些进程和线程的概念:
1. 进程:
进程是资源分配和独立运行的基本单位。进程的定义很多,下面列举一些
Ø 进程是程序的一次执行;
Ø 进程是可以和别的计算机并发执行的计算;
Ø 进程可定义为一个数据结构及能在其上进行操作的一个程序
Ø 进程是一个程序及其数据在处理机上顺序执行时发生的活动;
Ø 进程时程序在一个数据集合上的运行过程,时系统进行资源分配和调度的一个独立单位。
2. 线程
由于进程是一个资源拥有者,因而在进程的创建、撤消和切换过程中,系统必须为之付出较大的时空开销。也正因为如此,在系统中所设置的进程数目不宜过多,进程切换的频率也不宜过高,但这也就限制了并发程度的进一步提高。因此便引出了线程的概念
把线程作为调度和分派的基本单位,而把进程作为资源拥有的基本单位,使传统进程的两个属性分开,线程便能轻装运行,从而显著提高系统的并发程度。
Ø 在同一个进程内可以有多个线程;
Ø 同一个进程内的线程切换不会引起进程切换;
Ø 一个进程的线程切换到另一个进程的线程时会引起进程切换
3. JSP/SERVLET
而我们常用的jsp/ervlet这种j2ee的体系结构正是建立在java的多线程机制之上的。JSP/SERVLET容器会自动使用线程池等技术来支持系统的运行。因此,JSP/SERVLET的实质是一种线程技术,JSP会在运行时被编译成servlet来运行,如图所示:
当客户端向服务器发出一个请求时,servlet容器会分配一个线程专门处理这个请求,线程内容就是JSP/servlet应用程序。
这部分内容与本主体无关,只是顺便说说。
4. 线程池
首先介绍一下线程池:
线程的创建和销毁,以及切换,执行都是要耗费系统资源的。当系统访问量比较大的时候,服务器内就会创建太多的线程,直至资源完全消耗,这对于应用系统的正常运行是有致命伤害的。
为了能够在访问尖峰时限制活动线程的数量,同时减少线程频繁创建和销毁带来的系统开销,提高系统的大访问量的处理性能和速度,需要事先创建一定数量的线程供调用者循环反复使用,这就是“池”技术。
线程的基本原理是基于队列queue这种数据结构的,通过不断查询队列queue是否有可以运行的线程。如果有,就立即运行线程,没有,则锁定等待,直到有新的线程加入被解锁。(这种锁定机制,就是所谓的“信号量机制”)。
一种线程池必须解决如下的问题:死锁、资源不足、并发错误、线程泄漏和请求过载。下面我们具体举一个成熟的开源线程池的例子来说明线程池的原理:
PooledExecutor pool=new PooledExecutor(new BoundedBuffer(20),100);
pool.setMinimumPoolSize(10);//最小线程数为10
poole.setKeepAliveTime(-1);//线程一直运行
上面的语句设置了线程的最大数目为100,这样,就可以保护系统不会因为访问量增加导致线程数目的无限增加。使用该线程池如下:
pool.execute(java.lang.Runnable 自己的线程);
这一句实际上是将“自己的线程”加入一个队列中,而队列(先进先出FIFO)另一段正开启多个线程不断读取这个队列,一旦队列中有空闲的线程,线程管理器就将读取并分配线程来运行它。
public void execute(Runnable command) throws InterruptedException {
for (;;) { //一直循环
synchronized (this) {
if (!shutdown_) { //确保线程池没有关闭
int size = poolSize_; //当前线程池中线程的数目
if (size < minimumPoolSize_) { //如果当前线程数目少于线程池最小数目
addThread(command);
return;
}
//如果目前线程池中有超过或等于最小数目的线程
//分配一个存在的空闲线程来运行command,handOff是队列
if (handOff_.offer(command, 0)) {
return;
}
//如果不能分配已有的线程来运行command,那么创建一个新线程
if (size < maximumPoolSize_) {
addThread(command);
return;
}
}
}
//如果阻塞,则请求帮助
if (getBlockedExecutionHandler().bolckedAction(command)) {
return;
}
}
}
由上面的代码可见,PooledExecutor线程池的原理是,当执行execute加载一个应用系统的线程时,线程池内部首先检查当前线程数目是否达到设定的最小数目。如果没有达到,启动新线程运行;如果达到了,那么检查有无空闲线程可用;如果没有空闲的,则创建新线程,直到达到最大数目。
使用线程池的好处是:首先是循环使用,一经创建后,空闲的线程可以被反复使用,提高了运行效率;其次有最大数目的限制,保证了系统的安全性。
5. 连接池
终于轮到连接池了,通过上面的介绍,我们对线程及线程池都有个一个大致的了解。
在正常情况下,直接使用JDBC调用数据库可以满足一个小型系统的要求,但是当系统规模比较大的情况下,就会出现数据库的访问量迅速提升而令服务器不堪重负的现象,因而为了解决这一性能问题,常常会使用数据库连接池作为一个缓存的方式解决。
连接池类似上面介绍的线程池。
每次数据库连接的建立都需要花费一定的时空费用,而使用连接池,可以事先建立连接。当应用程序需要开始使用时,就从连接池中获取一个连接使用,应用程序使用完毕,通过close()方法将连接归还连接池。讲到这里,我门就不必在担心close()方法会不会影响性能了,完全可以放心大胆的使用。因为,它实际上并没有关闭连接,而是将连接归还连接池,供下次使用。
当并发增加是,连接池会不断的自动创建新的连接满足调用,直到达到连接池的最大数目;当连接池连接减少甚至没有时,连接池自动关闭一些连接,保持最小数目。
因此连接池的使用节省了连接建立时间,消除了数据库频繁连接带来的开销和瓶颈。
小提示:不知道大家有没有注意到配置websphere时有关于连接池最大最小数目的配置。呵呵,道理就在这。
那么,我们经常面对的连接未关闭的问题导致的系统速度很慢的问题就很容易说明了,就是因为线程池已经达到了最大数目,没有可用的了。所以,其他操作只有等待的份,等待那些应用用完了,被垃圾回收了,才能释放出可用的连接。
数据库连接池-连接的关闭内幕相关推荐
- Alibaba Druid 源码阅读(五)数据库连接池 连接关闭探索
Alibaba Druid 源码阅读(五)数据库连接池 连接关闭探索 简介 在上文中探索了数据库连接池的获取,下面接着初步来探索下数据库连接的关闭,看看其中具体执行了那些操作 连接关闭 下面的具体的代 ...
- mysql事务锁导致tomcat崩溃_数据库连接池连接耗尽,导致tomcat请求无响应,呈现出假死状态...
最困难的事情就是认识自己! 个人网站 ,欢迎访问! 前言:最近,测试部门的同事找到我,说他们测试时,没一会就发现服务接口请求一直无响应,Tomcat跟死掉了一样,也没有返回任何的错误响应,说让我赶紧排 ...
- net core mysql 连接池_EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽
EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽 发布时间:2019-02-18 22:05, 浏览次数:1152 , 标签: EF Core DbContextPool ...
- 数据库连接池连接异常com.alibaba.druid.pool.GetConnectionTimeoutException
数据库连接池连接异常com.alibaba.druid.pool.GetConnectionTimeoutException 参考文章: (1)数据库连接池连接异常com.alibaba.druid. ...
- ef mysql 连接数_EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽
原标题:EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽 DbContextPool 是 ASP.NET Core 2.1 引入的新特性,可以节省创建 DbContext ...
- 数据库连接池连接超时报错
文章目录 一.问题原因: 二.解决办法 1.重启服务器 2.连接池配置 1)数据库连接池增加探活配置(`推荐这种方式`) 2)增大数据库默认的超时等待时间(wait_timeout) 3)JDBC配置 ...
- 数据库连接池连接数量配置多大合理
前段时间在一个老项目中经历过一个问题:一个 Dubbo 服务,启动的时候慢的要死,后来看日志查原因整个过程一直在初始化数据库连接.一看数据库连接参数,连接池大小:1024. 很多入行晚的同学没有经历过 ...
- java使用数据库连接池连接MySQL/MariaDB--DBCP2
如果每次操作数据库都需要重新连接数据库,那么会很浪费资源.因此建议使用数据库的连接池来满足多线程的数据库操作. Java中数据库连接池有多种实现方法,推荐使用DBCP,这是Apache 提供的数据库连 ...
- EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽
DbContextPool 是 ASP.NET Core 2.1 引入的新特性,可以节省创建 DbContext 实例的开销,但没有想到其中藏着一个小坑. 最近有一个 ASP.NET Core 项目持 ...
最新文章
- JavaScript中变量的相互引用
- WinDbg实战调试命令笔记
- python 抽象类分析
- dtft变换的性质_[2018年最新整理]DTFT变换.ppt
- GitHub趋势:Vue.js大有超过TensorFlow之势!
- 利用python绘制雪景图_用AI绘制冬季雪景森林场景插画图片
- CyclicBarrier源码解读
- c语言编程线性规划,C语言大作报告_线性规划求解_基科3字班
- 穿衣助手 张凯:电商产品经理的成长之路
- c语言 最大子段和,C语言程序设计100例之(13):最大子段和
- 易控INSPEC软件与欧姆龙PLC以太网通讯
- 软件测试该怎么自学?
- 什么叫做罗列式_申论作文写作之案例罗列式开头
- 移动端APP测试总结(二)
- 打造一个生命周期感知的MVP架构
- CAD特性窗口,快捷特性窗口等不显示图形类型问题
- JSON.stringify 函数 (JavaScript)
- 辨别亦真亦假的Svchost.exe
- 用Python中的马尔科夫链进行营销渠道归因
- 莫烦python系列教程_莫烦python教程学习笔记——总结篇
热门文章
- TensorFlow模型实现:UNet模型
- (一)SpringBoot 整合 MyBatis
- Java中for循环continue,break,return三者之间的关系
- Python定义点击右上角关闭按钮事件
- 【LeetCode】36. Valid Sudoku
- MyEclipse中导入Spring 4.0源码
- 微软并行编程类库Parallel Extensions初探 Part1
- 【转】在你的博客中添加Google地图(Use Google Map API On Your Bolg)
- Java集合框架体系(超详细)
- 一千行 MySQL 学习笔记