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

线程池实现原理_最通俗易懂的解读比特币相关原理本篇内容综合广大网友提供内容,笔者经过整理,对数据库连接池原理和实现过程做个很系统的并且通俗易懂的分析讲解,以及手写一个连接池实现过程作为演示。一、早期通过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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 股票API

    实时股票数据接口大全股票数据的获取目前有如下两种方法可以获取:1.http/javascript接口取数据2.web-service接口1.http/javascript接口取数据1.1Sina股票数据接口以大秦铁路(股票代码:601006)为例,如果要获取它的最新行情,只需访问新浪的股票数据接口:http://hq.sinajs…

  • Idea激活码永久有效Idea2021.3.2激活码教程-持续更新,一步到位

    Idea激活码永久有效Idea2021.3.2激活码教程-持续更新,一步到位Idea激活码永久有效2021.3.2激活码教程-Windows版永久激活-持续更新,Idea激活码2021.3.2成功激活

  • 流水线设计的方法和作用「建议收藏」

    流水线设计的方法和作用「建议收藏」流水线设计从某种程度上可以提高系统频率,因此常用于高速信号处理领域,如果某个信号可以分为若干步骤处理,而且整个数据处理过程是单项的,即没有反馈运算和迭代运算,前一个步骤的输出就是下一个步骤的输入,可以考虑流水线设计来提高系统的频率。如下图所示:典型的流水线设计是将原本一个时钟周期完成的较大的组合逻辑通过合理的切割后分由多个时钟周期来完成,这样一来该部分逻辑运行的时钟频率就会有明显的提升,尤其当她是…

  • laravel之phpunit单元测试

    laravel之phpunit单元测试laravel之phpunit单元测试

  • js 字串转换HTML,js转化html字符

    js 字串转换HTML,js转化html字符/*1.用浏览器内部转换器实现html转码*/htmlEncode:function(html){//1.首先动态创建一个容器标签元素,如DIVvartemp=document.createElement(“div”);//2.然后将要转换的字符串设置为这个元素的innerText(ie支持)或者textContent(火狐,google支持)(temp.textContent!=u…

  • 十七、访问者模式-访问数据结构并处理数据 #和设计模式一起旅行#「建议收藏」

    看过千山万水,依旧走不出自己的内心世界!故事背景Vistor : 访客,参观者,访问,本篇就讲讲Vistor模式,也就访问模式!有时候在软件开发中,我们会在一个数据结构中存放许多不同类型的对象信息,而且对每一个对象的处理方式并不相同,就存在数据结构对象内容的存放和数据的处理如何进行合理的设计! 如果将数据的处理和数据结构存放在一起,那么如果要新增一些对象信息的话,就需要修改…

发表回复

您的电子邮箱地址不会被公开。

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