线程池实现原理_最通俗易懂的解读比特币相关原理

线程池实现原理_最通俗易懂的解读比特币相关原理本篇内容综合广大网友提供内容,笔者经过整理,对数据库连接池原理和实现过程做个很系统的并且通俗易懂的分析讲解,以及手写一个连接池实现过程作为演示。一、早期通过JDBC方式操作数据库我们先来看早期使用JDBC的方式操作数据库的过程,这里以mysql数据库为例讲解JDBC操作数据库原理:一般来说,java应用程序访问数据库的过程是:   ①装载数据库驱动程序;   ②通过jdbc…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

本篇内容综合广大网友提供内容,笔者经过整理,对数据库连接池原理和实现过程做个很系统的并且通俗易懂的分析讲解,以及手写一个连接池实现过程作为演示。

一、早期通过JDBC方式操作数据库

我们先来看早期使用JDBC的方式操作数据库的过程,这里以mysql数据库为例讲解

线程池实现原理_最通俗易懂的解读比特币相关原理

JDBC操作数据库原理:一般来说,java应用程序访问数据库的过程是:

   ①装载数据库驱动程序;

   ②通过jdbc建立数据库连接;

   ③访问数据库,执行sql语句;

   ④断开数据库连接。

1、具体的代码实现步骤

创建数据库配置文件db.properties ,配置文件内容如下:

#连接数据库的url,test表示数据库名,useUnicode=true表示使用Unicode字符集
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8; 
#用户名
user=root
#密码
password=root
#MySQL数据库加载驱动
driverClass=com.mysql.jdbc.Driver

定义一个使用jdbc连接数据库的工具类JdbcUtil.java

public class JdbcUtil{
    //定义全局变量
    private static String url = null;
    private static String user = null;
    private static String password = null;
    private static driverClass = null;
    //读取配置文件内容,放在静态代码块中就行,因为只需要加载一次就可以了
    static{
        try{
            Properties props = new Properties();
            //使用类路径加载的方式读取配置文件
            //读取的文件路径要以“/”开头,使用"/"开头会直接定位到工程的src路径下
            InputStream in = JdbcUtil.class.getResourceAsStream("/db.properties");
            //加载配置文件
            props.load(in);
            //读取配置文件信息
            url = props.getProperty("url");
            user = props.getProperty("user");
            password = props.getProperty("password");
            driverClass = props.getProperty("driverClass");
            //动态注册mysql驱动程序
            Class.forName(driverClass);
            System.out.println("成功加载MySQL驱动程序");
        }catch(Exception e){
            e.printStackTrace();
            System.out.println("mysql驱动程序注册失败!!!");
        }
    }

    //获取连接对象Connection
    public static Connection getConnection(){
        try{
            //要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象
            return DriverManager.getConnection(url,user,password);
        }catch(SQLException e){
            e.printStackTrace();
            //抛出运行时异常
            throw new RuntimeException();
        }
    }

    //关闭连接的方法,后打开的先关闭
    public static void close(Connection conn,Statement stmt,ResultSet rs){
        //关闭ResultSet对象
        if(rs != null){
            try{
                //关闭rs,设置rs=null,因为java会优先回收值为null的变量
                rs.close();
                rs = null;
            }catch(SQLException e){
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
        //关闭Statement对象,因为PrepareStatement和CallableStatement都是Statement的子接口,所以这里只需要有关闭Statement对象的方法就可以了
        if(stmt != null){
            try{
                stmt.close();
                stmt = null;
            }catch(SQLException e){
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
        //关闭Connection对象
        if(conn != null){
            try{
                conn.close();
                conn = null;
            }catch(SQLException e){
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
    }
}

到此,这是一个完整的使用JDBC方式操作数据库的过程,下面我们新建一个测试类TestConn.java 测试一下

package demo;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import utils.JdbcUtil;

public class TestConn {

	public static void main(String[] args) {
	// TODO Auto-generated method stub
	Connection conn = JdbcUtil.getConnection();
	  try {
		Statement stmt = conn.createStatement();
		ResultSet rs = stmt.executeQuery("SELECT * FROM user") ;
		//使用结果集(ResultSet)对象的访问方法获取数据:
		 while(rs.next()){   
	         String name = rs.getString("name") ; 
	         System.out.println(name);
	         String pass = rs.getString(1);//此方法比较高效,列是从左到右编号的,并且从列1开始 
	         System.out.println(pass);
	     } 
		 //操作完成以后关闭JDBC对象,要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反: 
		 //关闭顺序1、关闭记录集,2、关闭声明,3、关闭连接对象
		 JdbcUtil.close(conn, stmt, rs);
	  } catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	  }
	}
}

2、分析

       程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

       上述的用户查询案例,如果同时有1000人访问,就会不断的有数据库连接、断开操作:

线程池实现原理_最通俗易懂的解读比特币相关原理

通过上面的分析,我们可以看出来,“数据库连接”是一种稀缺的资源,为了保障网站的正常使用,应该对其进行妥善管理。其实我们查询完数据库后,如果不关闭连接,而是暂时存放起来,当别人使用时,把这个连接给他们使用。就避免了一次建立数据库连接和断开的操作时间消耗。原理如下:

线程池实现原理_最通俗易懂的解读比特币相关原理

二、技术演进出来的数据库连接池

       由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

       我们自己尝试开发一个连接池,来为上面的查询业务提供数据库连接服务:

       ①   编写class 实现DataSource 接口

       ②   在class构造器一次性创建10个连接,将连接保存LinkedList中

       ③   实现getConnection  从 LinkedList中返回一个连接

       ④   提供将连接放回连接池中方法

1、实现mysql数据库连接池代码 

public class MyDataSource implements DataSource {
    //链表实现栈结构
    privateLinkedList<Connection> dataSources = new LinkedList<Connection>();
    //无参构造器,初始化连接数量
    public MyDataSource() {
         //一次性创建10个连接
         for(int i = 0; i < 10; i++) {
            try {
              //1、获取数据库连接对象
              Connection conn = JdbcUtil.getConnection();
              //2、将连接加入连接池中
              dataSources.add(con);
            } catch (Exception e) {
              e.printStackTrace();
          }
       }
     }
 
     @Override
     public Connection getConnection() throws SQLException {
         //取出连接池中一个连接
         final Connection conn = dataSources.removeFirst(); //删除第一个连接返回
         return conn;
     }
 
     //将连接放回连接池
     public void releaseConnection(Connection conn) {
         dataSources.add(conn);
     }
}

这就是数据库连接池的原理,它大大提供了数据库连接的利用率,减小了内存吞吐的开销。我们在开发过程中,我们只关注我们的业务代码的开发,就不需要再关心数据库连接的问题,自然有数据库连接池帮助我们处理。但连接池需要考虑的问题不仅仅如此,还有更多问题需要考虑,在下一节内容中具体分享。

欢迎广大开发者朋友交流,学习,笔者电话(微信):18629374628

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/192999.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SQL like 模糊查询

    SQL like 模糊查询SQL模糊查询在进行数据库查询时,有完整查询和模糊查询之分。一般模糊查询语句如下:SELECT字段FROM表WHERE某字段Like条件其中关于条件,SQL提供了四种匹配模式:1,% :表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。

    2022年5月2日
    46
  • springMVC 防重校验(拦截器)[通俗易懂]

    springMVC 防重校验(拦截器)[通俗易懂]springMVC 防重校验(拦截器)

    2022年4月20日
    71
  • Applet 数字签名技术完全攻略

    Applet 数字签名技术完全攻略

    2021年12月17日
    37
  • Java在字符串中查找匹配的子字符串

    Java在字符串中查找匹配的子字符串Java在字符串中查找匹配的子字符串

    2022年7月16日
    134
  • php开源的客服系统_在线客服源码php

    php开源的客服系统_在线客服源码php在线客服系统软件使开发和运营团队能够高速协作,因此要求源码系统能够快速响应业务变化,并快速提供出色的客户和员工服务体验。  在线客服源码演示及获取:https://gitee.com/wang_li989/kfxt  客服沟通问题加起来会成为重大的财务损失。您的组织快速有效地解决这些问题的能力直接影响到未满足的SLA义务和客户体验,这两个方面对公司的成功至关重要。在线客服系统是企业战略的核心组成部分。通过减少识别和解决问题所需的时间,您的组织可以提高客户忠诚度,最大限度地延长正常运行时间,并提供始终如

    2022年4月19日
    49
  • Modifying BAQ to query with parameters「建议收藏」

    Modifying BAQ to query with parameters「建议收藏」//DynamnicQueryforBAQEpicor.Mfg.Core.SessionepiSession=default(Epicor.Mfg.Core.Session);epiSession=(Epicor.Mfg.Core.Session)POEntryForm.Session;DynamicQuerydynamicQ

    2022年6月17日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号