JDBC中数据库连接池的使用与传统方式的比较
数据库连接的传统方式
当有多个线程,每个线程都需要连接数据库执行SQL语句的话,那么每个线程都会创建一个连接,并且在使用完毕后,关闭连接。创建连接和关闭连接的过程也是比较费时间的,当多线程并发的时候,系统就会变得卡顿。并且,一个数据库同时支持的连接综述也是有限的,如果多线程并发量很大,那么数据库连接的总数就会被消耗光,后续线程发起的数据库连接就会失效。
数据库连接池原理-使用池
与传统方式不同,连接池在使用之前,就会创建好一定数量的连接。
如果有任何线程需要使用连接,那么就从连接池里面借用,而不是自己重新创建.
使用完毕后,又把这个连接归还给连接池供下一次或者其他线程使用。
倘若发生多线程并发情况,连接池里的连接被借用光了,那么其他线程就会临时等待,直到有连接被归还回来,再继续使用。
整个过程,这些连接都不会被关闭,而是不断的被循环使用,从而节约了启动和关闭连接的时间。
ConnectionPool构造方法和初始化
1.ConnectionPool()构造方法规定连接池一共有多少连接
2.在init() 初始化方法中,创建了size条连接。 注意,这里不能使用try-with-resource这种自动关闭连接的方式,因为连接恰恰需要保持不关闭状态,供后续循环使用
3.getConnection(), 判断是否为空,如果是空的就wait等待,否则就借用一条连接出去
4.returnConnection(), 在使用完毕后,归还这个连接到连接池,并且在归还完毕后,调用notifyAll,通知那些等待的线程,有新的连接可以借用了
package jdbc;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class ConnectionPool {List<Connection> cs = new ArrayList<Connection>();int size;public ConnectionPool(int size) {this.size = size;init();}public void init() {//这里恰恰不能使用try-with-resource的方式,因为这些连接都需要是"活"的,不要被自动关闭了try {Class.forName("com.mysql.jdbc.Driver");for (int i = 0; i < size; i++) {Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin");cs.add(c);}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public synchronized Connection getConnection() {while (cs.isEmpty()) {try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}Connection c = cs.remove(0);return c;}public synchronized void returnConnection(Connection c) {cs.add(c);this.notifyAll();}}
测试类
首先初始化一个有3条连接的数据库连接池
然后创建100个线程,每个线程都会从连接池中借用连接,并且在借用之后,归还连接。 拿到连接之后,执行一个耗时1秒的SQL语句。
运行程序,就可以观察到如图所示的效果
使用例子来比较传统方式和数据库连接池的性能差异
向数据库中插入100条数据,比较传统方式和数据库连接池方式的性能差异
使用传统方式创建100个线程,每个线程都会创建新的连接,通过这个连接向数据库插入1条数据,然后关闭这个连接。
使用数据库连接池的方式,创建一个有10条连接的连接池,然后创建100个线程,每个线程都会向连接池借用连接,借用到后,向数据库插入1条数据,然后归还这个连接。
通过时间统计,比较这两种方式的性能表现差异。
package jdbc;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;/**
使用传统方式,建立连接的线程
*/
class TraditionalWorkingThread extends Thread {public void run() {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/LOL?characterEncoding=UTF-8","root", "admin"); Statement st = c.createStatement()) {for (int i = 0; i < TestConnectionPool.insertTime; i++) {String sql = "insert into hero values(null," + "'提莫'" + "," + 313.0f + "," + 50 + ")";st.execute(sql);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
package jdbc;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;/*
使用连接池方式,建立连接的工作线程
*/
class ConnectionpoolWorkingThread extends Thread {private ConnectionPool cp;public ConnectionpoolWorkingThread(ConnectionPool cp) {this.cp = cp;}public void run() {Connection c = cp.getConnection();try (Statement st = c.createStatement()) {for (int i = 0; i < TestConnectionPool.insertTime; i++) {String sql = "insert into hero values(null," + "'提莫'" + "," + 313.0f + "," + 50 + ")";st.execute(sql);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}cp.returnConnection(c);}
}
package jdbc;import java.util.ArrayList;
import java.util.List;/**
测试类,在这个类中分别创建了100个TraditionalWorkingThread 和100ConnectionpoolWorkingThread ,并分别统计他们运行需要的时间
*/
public class TestConnectionPool {private static int threadNumber = 100;public static int insertTime = 1;public static void main(String[] args) {traditionalWay();connectionPoolWay();}private static void connectionPoolWay() {ConnectionPool cp = new ConnectionPool(10);System.out.println("开始连接池方式插入数据测试:");long start = System.currentTimeMillis();List<Thread> ts = new ArrayList<>();for (int i = 0; i < threadNumber; i++) {Thread t =new ConnectionpoolWorkingThread(cp);t.start();ts.add(t);}//等待所有线程结束for (Thread t : ts) {try {t.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}long end = System.currentTimeMillis();System.out.printf("使用连接池方式,启动%d条线程,每个线程插入%d条数据,一共耗时%d 毫秒%n",threadNumber,insertTime,end-start);}private static void traditionalWay() {System.out.println("开始传统方式插入数据测试:");long start = System.currentTimeMillis();List<Thread> ts = new ArrayList<>();for (int i = 0; i < threadNumber; i++) {Thread t =new TraditionalWorkingThread();t.start();ts.add(t);}//等待所有线程结束for (Thread t : ts) {try {t.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}long end = System.currentTimeMillis();System.out.printf("使用传统方式,启动%d条线程,每个线程插入%d条数据,一共耗时%d 毫秒%n",threadNumber,insertTime,end-start);}
}
当测试有100线程时,传统方式大约为1000ms,使用数据库连接池大约是500毫秒,节省了约1倍的时间。
JDBC中数据库连接池的使用与传统方式的比较相关推荐
- Java -- JDBC 学习--数据库连接池
JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet.beans)中建立数据库连接. 进行sql操作 断开数据库连接. 这种模式开 ...
- Java JDBC和数据库连接池 韩顺平老师自学笔记
JDBC和数据库连接池 JDBC 概述 基本介绍 原理示意图 代码示例 JdbcInterface 模拟Java公司提供给其它数据库厂商的接口,供给调用 TestJdbc 模拟一个类来实现数据库的调用 ...
- JavaWeb:JDBC之数据库连接池
JDBC系列阅读 JavaWeb:用JDBC操作数据库 JavaWeb:JDBC之事务 JavaWeb:JDBC之数据库连接池 使用JDBC实现水果超市管理系统 1. 池参数(所有池参数都有默认值) ...
- 【JDBC】数据库连接池技术
文章目录 一.数据库连接池技术 二.多种开源的数据库连接池 一.数据库连接池技术 1.数据库连接池的基本思想︰ 就是为数据库连接建立一个"缓冲池".预先在缓冲池中放入一定数量的连接 ...
- JDBC以及数据库连接池的使用
文章目录 JDBC 步骤 数据库连接池 1.概念 2.接口规范方法 3.第三方数据库连接池技术 C3p0 Druid:由阿里提供 Druid工具类 JDBC 概念 JDBC是sun公司提供的一套用 ...
- java 连接池配置_java数据库连接池配置的几种方式
关于java数据库连接池配置的几种方式 今天遇到了关于数据源连接池配置的问题,发现有很多种方式可以配置,现总结如下,(已Mysql数据库为例) 一,Tomcat配置数据源: 方式一:在WebRoot下 ...
- kylin调优,项目中错误总结,知识点总结,kylin jdbc driver + 数据库连接池druid + Myba
首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的.教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈-我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转 ...
- kylin调优,项目中错误总结,知识点总结,kylin jdbc driver + 数据库连接池druid + Mybatis项目中的整合,shell脚本执行kylin restapi 案例
关于本篇文章的说明: 本篇文章为笔者辛苦劳作用了一整天总结出来的文档,大家阅读转发的时候请不要吝啬写上笔者:涂作权 和 原文地址. 由于笔者所在环境没有人用过kylin,笔者也是自学官网,阅读书籍 将 ...
- 基于JDBC的数据库连接池技术研究与应用
引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机 应用程序已从传统的桌面应用转到Web应用.基于B/S(Browser/Server)架构的3层开 ...
- JDBC系列(九):JDBC与数据库连接池(Druid-德鲁伊)使用步骤
目录 1.导语(唠唠嗑~~~) 2.使用数据库连接池好处 3.Druid数据库连接池创建与使用步骤 3.1.创建连接池的步骤 3.2使用Druid数据库连接池的步骤 4.关闭资源与归还至连接池的一点说 ...
最新文章
- 如何让我们的vmware虚拟机上网!!
- Spark发布1.3.0版本
- 机器人 陆梅东_上海乐高创客工作坊活动顺利举行
- Nginx中浏览器缓存的执行流程
- java相遇问题_行程问题
- react hooks_为什么选择React Hooks,我们如何到达这里?
- php怎么调用dll例子,php调用dll的实例操作动画与代码分享_PHP教程
- 2020年进入倒计时:一波前端资源送给你~这一年,谢谢自己!
- HDOJ 2896 病毒侵袭(AC自动机入门)
- Android指定SDK编译版本
- MyBatis学习(一):简单的运行
- Java记录 -59- SortedSet
- 十进制、二进制、八进制、十六进制转换
- 开发者经验谈:如何一天时间搞定iOS游戏开发?
- Mac终端adb安卓刷机
- 如何实现thead固定不动,tbody出现垂直滚动条
- 【五线谱】重音记号、渐强记号、渐弱记号
- 我的JAVA面试经验(5年左右工作经验)
- 数据挖掘里的“降维”----从五阶魔方的玩法思考
- svn服务端和客户端下载网址