连接池
1.线程池介绍
1.作用:
- 它是预先创建线程的一种技术,减少频繁的创建和销毁对象
连接池就是存储连接的一个容器,容器就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一连接,该集合还必须实现队列的特性,先进先出。
2.四种策略:
- 如果线程数小于corePoolSize,则每来一个任务,就会创建执行这个任务。
- 如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列中。若添加失败(一般来说是任务缓存队列已满,针对的是有界队列),则会尝试创建新的线程去执行这个任务。
- 如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理
- 如果线程池的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTIme,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程池空闲时间超过keepAliveTime,线程也会被终止。
连接池介绍[实际开发中都会使用连接池]:
优点:因为它可以减少获取连接时间
mybaits中的连接池
- mybatis连接池提供了3种方式配置
- 配置的位置
主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式。 - type属性的取值:
- POOLED:采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。
- UNPOOLED:采用传统的获取连接的方式,虽然也实现了Javax.sql.DataSource接口看,但是并没有使用连接池思想。【这个表示没有连接池】
- JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的连接池对象是不一样的,它是服务器中的连接池,tomcat使用的就是dbcp。
POOLED:
使用了连接池技术,在执行过程中可以看到,该连接方式创建了连接池对象,关闭连接对象,归还连接对象。
源码分析:
synchronized锁 -->所以它是线程安全的。
new ArrayList -->所以它的容器是一个集合对象
执行的步骤:
- 先看是否有空闲状态下的PooledConnecttion对象;如果有,就直接返回一个可用的PooledConnection对象;[state.idleConnections.remove(0)–>将空闲池中第0个连接池移出使用。]否则进行第二步;
- 查看活动状态的PooledConnection池activeConnection是否已满;如果没有满,则创建一个新的PooledConnection对象,然后放到activeConnection池中,然后返回此PooledConnection对象;否则进行第三步。
- 看最先进入activeCOnnections池中的PooledConnection对象是否已经过期:如果过期,从activeConnection池中移出此对象,然后创建一个新的PooledConnection对象,添加到activeConnections中,然后将此对象返回,否则进行第4步。
- 线程等待,循环第2步。
UNPOOLED:
源码中->注册驱动,获取连接 【所以它未使用连接池技术】
配置信息:
- 空闲池数量:5个 [数组结构]
- 活动池数量:10个 [集合]
执行步骤:- 当我们第一次进来获取连接的时候,先判断空闲连接池中是否还有连接?
如果有连接:取出第一个连接出来idleConnections.remove(0),返回!
如果没有连接:判断活动连接池中数量是否达到最大10个? - 判断:活动连接池数量是否达到最大值10?
如果没有达到10个,则创建一个新的连接放入activeConnections中,返回!
如果活动连接池数量等于最大值10个,则获取出第0个连接,也就是最先使用的那个连接 - 判断:获取的这个第0个连接对象是否超时[过期],参照:如果大于poolMaximumCheckoutTime=20000;
如果过期,则把这个老的连接对象进行包装,重新使用
如果没有过期,线程等待,循环第二个判断 - 连接池中的连接对象最多能创建多少个? -->10个 一开始有5个,最多还能再创建5个。
- 当我们第一次进来获取连接的时候,先判断空闲连接池中是否还有连接?
JNDI:在maven项目下,有Tomcat才行
1.JNDI的数据结构
winndows注册表结构。
作用:使用map结构存储数据,存储到服务器内存中。
map的key是由路径和名称组成的。
路径是固定的。
名称可以自定义。
value是自己指定的任意对象。
2.JNDI连接
1.配置SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入约束 -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.itheima.domain"></package>
</typeAliases>
<!-- 配置mybatis的环境 -->
<environments default="mysql">
<!-- 配置mysql的环境 -->
<environment id="mysql">
<!-- 配置事务控制的方式 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的必备信息 type属性表示是否使用数据源(连接池)-->
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/eesy_mybatis"/>
</dataSource>
</environment>
</environments>
<!-- 指定mapper配置文件的位置 -->
<mappers>
<mapper resource="com/itheima/dao/IUserDao.xml"/>
</mappers>
</configuration>
2.在webapp目录下创建META-INF文件夹并创建context.xml
* 写入内容:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
<Resource
name="jdbc/eesy_mybatis" 数据源的名称
type="javax.sql.DataSource" 数据源类型
auth="Container" 数据源提供者
maxActive="20" 最大活动数
maxWait="10000" 最大等待时间
maxIdle="5" 最大空闲数
username="root" 用户名
password="1234" 密码
driverClassName="com.mysql.jdbc.Driver" 驱动类
url="jdbc:mysql://localhost:3306/eesy_mybatis" 连接url字符串
/>
-->
<Resource
name="jdbc/eesy_mybatis"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/eesy_mybatis"
/>
</Context>