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

  数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。

以下是传统的链接方式和连接池的对比:


现在可以自己做一个实例,写一个连接池的测验

假定现在连接池的最大上限是6个,初始化的连接池中有三个,可以按以下步骤完成代码

自定义连接池, 管理连接
代码实现:
1. MyPool.java 连接池类,
2. 指定全局参数: 初始化数目、最大连接数、当前连接、 连接池集合
3. 构造函数:循环创建3个连接
4. 写一个创建连接的方法
5. 获取连接
------> 判断: 池中有连接, 直接拿
------> 池中没有连接,
------> 判断,是否达到最大连接数; 达到,抛出异常;没有达到最大连接数,
创建新的连接
6. 释放连接
-------> 连接放回集合中(..)

  1. package com.connectionPool;
  2.  
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Proxy;
  6. import java.sql.Connection;
  7. import java.sql.DriverManager;
  8. import java.sql.SQLException;
  9. import java.util.LinkedList;
  10.  
  11. /**
  12. * 自定义连接池, 管理连接
  13. * 代码实现:
  14. 1. MyPool.java 连接池类,
  15. 2. 指定全局参数: 初始化数目、最大连接数、当前连接、 连接池集合
  16. 3. 构造函数:循环创建3个连接
  17. 4. 写一个创建连接的方法
  18. 5. 获取连接
  19. ------> 判断: 池中有连接, 直接拿
  20. ------> 池中没有连接,
  21. ------> 判断,是否达到最大连接数; 达到,抛出异常;没有达到最大连接数,
  22. 创建新的连接
  23. 6. 释放连接
  24. -------> 连接放回集合中(..)
  25. *
  26. */
  27. public class MyPool {
  28. private int init_count=3; ////初始化连接数目;
  29. private int max_count=6; //最大连接数目
  30. private int current_count=0; //记录当前的连接数
  31. //连接池,存放所有初始化连接
  32. private LinkedList<Connection> pool=new LinkedList<Connection>();
  33.  
  34. //1、构造函数,初始化连接放入连接池中
  35. public MyPool(){
  36. //初始化
  37. for (int i = 0; i < 3 ; i++) {
  38. //把连接加入连接池
  39. current_count ++;
  40. final Connection connection=createConnection();
  41.  
  42. pool.addLast(connection);
  43. }
  44. }
  45.  
  46. //2、创建一个新的连接方法
  47. public Connection createConnection(){
  48. try {
  49. Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
  50. String url="jdbc:sqlserver://localhost:1433;DataBaseName=Test";
  51. String user="sa";
  52. String pass="123456";
  53. final Connection connection= DriverManager.getConnection(url,user,pass);
  54. //对connection创建其代理对象
  55. /**********************对对象代理***************/
  56. Connection proxyConnection=(Connection)Proxy.newProxyInstance(
  57. connection.getClass().getClassLoader(), //类加载器
  58. //connection.getClass().getInterfaces(), //目标对象实现的接口
  59. new Class[]{Connection.class}, //目标对象实现的接口
  60. new InvocationHandler() { //当调用对象方法的时候,会自动出发本代码。
  61. @Override
  62. public Object invoke(Object proxy, Method method, Object[] args)
  63. throws Throwable {
  64. Object result=null;
  65. //当前执行的方法的方法名
  66. String methodName=method.getName();
  67.  
  68. //判断当执行了close方法的时候,把链接放入连接池
  69. if ("close".equals(methodName)) {
  70. System.out.println("begin:当前执行close方法");
  71. current_count--;
  72. pool.add(connection);
  73. System.out.println("当前连接已放入连接池!");
  74. }else {
  75. //调用目标对象方法
  76. result=method.invoke(connection, args);
  77. }
  78. //调用目标对象方法
  79. result=method.invoke(connection, args);
  80. return result;
  81. }
  82. });
  83. return proxyConnection;
  84. } catch (Exception e) {
  85. // TODO Auto-generated catch block
  86. throw new RuntimeException();
  87. }
  88. }
  89.  
  90. //3、获取连接,外界没必要获取这个方法,内部判断生成
  91. private Connection getConnection(){
  92. //1、判断连接池中是否有链接,如果有连接,直接从连接池中获取
  93. if (pool.size()>0) {
  94. return pool.removeFirst();
  95. }
  96. //2、连接池中没有连接,判断,如果没有到达最大连接数目,创建
  97. if (current_count<max_count) {
  98. //记录当前使用的连接数
  99. current_count++;
  100. //创建连接
  101. return createConnection();
  102. }
  103. //3、如果当前已经到达最大的连接数目,抛出异常
  104. throw new RuntimeException("当前链接数目已达到最大连接限度!");
  105. }
  106.  
  107. //4、释放连接
  108. public void realeaseConnection(Connection connection){
  109. //判断池的数目如果小于初始化数目
  110. if (pool.size()<init_count) {
  111. current_count--;
  112. pool.add(connection);
  113. }else {
  114. //关闭
  115. try {
  116. connection.close();
  117. } catch (SQLException e) {
  118. // TODO Auto-generated catch block
  119. e.printStackTrace();
  120. }
  121. }
  122. }
  123. public static void main(String[] args) throws SQLException {
  124. // TODO Auto-generated method stub
  125. MyPool pool=new MyPool();
  126. System.out.println("当前连接数目:"+pool.current_count);
  127.  
  128. //使用连接
  129. pool.getConnection();
  130. pool.getConnection();
  131. Connection con1=pool.getConnection();
  132. Connection connection=pool.getConnection();
  133.  
  134. pool.realeaseConnection(connection);
  135. /*
  136. * 希望:当关闭连接的时候,要把连接放入连接池!【当调用Connection接口的close方法时候,希望触发pool.addLast(con);操作】
  137. * 把连接放入连接池
  138. * 解决1:实现Connection接口,重写close方法,单Connection接口的方法是在太多了。
  139. * 解决2:动态代理
  140. * (1)、Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
  141. * (2)该类下有newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 方法
  142.      * 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
  143. * ClassLoad:当前使用的类加载器
  144.      * Class<?> interface 目标对象(Connection)实现的接口类型
  145.      * invocationHandler h 事务处理器,当执行上面接口中的方法的时候,就会自动触发
  146.      * 事件处理器的代码,把当前执行方法(method)作为参数传入。
  147.      * InvocationHandler invoke(Object proxy, Method method, Object[] args) 在代理实例上处理方法调用并返回结果。
  148.      *
  149. */
  150. con1.close();
  151. System.out.println("连接池:"+pool.pool.size());
  152. System.err.println("当前连接数目:"+pool.current_count);
  153. }
  154.  
  155. }

 运行结果(其中讲到了一个重要的概念:事务代理,当我们想要给close()方法添加一个必要的方法,当执行close方法的时候,我们想将其加入到连接池中,相当于把close当做一个触发器,一旦执行,就会自动的触发将其加入缓冲池中)

Java_Web 连接池的更多相关文章

  1. 连接SQLServer时,因启用连接池导致孤立事务的原因分析和解决办法

    本文出处:http://www.cnblogs.com/wy123/p/6110349.html 之前遇到过这么一种情况: 连接数据库的部分Session会出现不定时的阻塞,这种阻塞时长时短,有时候持 ...

  2. C3p0连接池配置

    在Java开发中,使用JDBC操作数据库的四个步骤如下:   ①加载数据库驱动程序(Class.forName("数据库驱动类");)   ②连接数据库(Connection co ...

  3. Java第三方数据库连接池库-DBCP-C3P0-Tomcat内置连接池

    连接池原理 数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”.预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去.我们可以通过设定连接池 ...

  4. common-pool2 学习:thrift连接池的另一种实现

    对象池是一种很实用的技术,经典的例子就是数据库连接池.去年曾经从零开始写过一个thrift客户端连接池.如果不想重造轮子,可以直接在apache开源项目commons-pool的基础上开发. 步骤: ...

  5. druid连接池获取不到连接的一种情况

    数据源一开始配置: jdbc.initialSize=1jdbc.minIdle=1jdbc.maxActive=5 程序运行一段时间后,执行查询抛如下异常: exception=org.mybati ...

  6. C3P0连接池配置和实现详解

    一.配置 <c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> ...

  7. hibernate+mysql的连接池配置

    1:连接池的必知概念    首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...

  8. 连接池的实现 redis例子

    # -*- encoding:utf-8 -*- # import pymysql # # conn = pymysql.connect(host="127.0.0.1", por ...

  9. DBCP连接池配置示例

    <bean id="dataSourceOracle2" class="org.apache.commons.dbcp.BasicDataSource" ...

随机推荐

  1. C语言和C++中动态申请内存

      在C语言和C++的动态内存的使用方法是不同的,在C语言中要使用动态内存要包含一个头文件即 #include<malloc.h> 或者是#include<stdlib.h>  ...

  2. Qt之json解析

    Jsoner::Jsoner(QObject *parent) : QObject(parent){    QJsonObject json;    json.insert("loginna ...

  3. vs2010 使用SignalR 提高B2C商城用户体验(一)

    vs2010 使用SignalR 提高B2C商城用户体验(一) 1.需求简介,做为新时代的b2c商城,没有即时通讯,怎么提供用户粘稠度,怎么增加销量,用户购物的第一习惯就是咨询,即时通讯,应运而生.这 ...

  4. Java编程规范整理

    分享一份网友整理的编程过程中的命名规范 包命名 包名按照域名的范围从大到小逐步列出,恰好和Internet上的域名命名规则相反. 由一组以"."连接的标识符构成,通常第一个标识符为 ...

  5. csu 10月 月赛 A 题

    Welcome to CSU OnlineJudge Problem A: Small change Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 15 ...

  6. 如何解决jquery版本冲突

    <!-- 引入1.6.4版的jq --> <script src="<a href="http://ajax.googleapis.com/ajax/lib ...

  7. AJAX里调用AJAX,作定时进度刷新

    这个确实搞了一段时间,但成就感有啦... 哈哈,这个自动部署平吧,异步队列CELERY+REDIS,发布进度实时AJAX的技术点全部打通!!! 而获取实时进度,我用的是RESTFUL FRAMEWOR ...

  8. VS2008编译器编译出来的文件比mingw编译的要几乎小一半

    为什么要在VS2008中使用QT静态编译呢?很简单,因为VS2008编译器编译出来的文件比mingw编译的要几乎小一半. 好了现在我们来做些准备工作,VS2008自然要安装的,然后打上SP1的补丁.然 ...

  9. Android Gson使用笔记

    最近在做一个java web service项目,需要用到jason,本人对java不是特别精通,于是开始搜索一些java平台的json类库. 发现了google的gson,因为之前对于protoco ...

  10. 使用Java正则表达式的分组解析身份证的年月日

    根据Java的Pattern和Matcher类通过分组解析出身份证的年月日: public class GetDateInIdCard { public static void main(String ...