数据库连接池、静态连接,普通连接的比较2(多线程)

1.前言

  本篇文章是继续上一篇针对于多线程情况下对数据库连接池、静态连接和普通连接的测试例子,最后给出这三种方式的比较。

2.使用数据库连接池

  1)编写测试类Test.java

public class Test {
public static void main(String[] args) {
MyThread[] threads = new MyThread[6];
for(int i=0;i<threads.length;i++){
threads[i] = new MyThread();
}
for(int i=0;i<threads.length;i++){
threads[i].start();
}
}

}

  2)编写线程类MyThread.java

public class MyThread extends Thread{
@Override
public void run() {
//获取连接池对象
ConnectionPool pool = ConnectionPool.getInstance();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
long startTime = System.currentTimeMillis();
try {
conn = pool.getConnection();
ps = conn.prepareStatement("select * from bms_weekreport");
rs = ps.executeQuery();
rs.next();
System.out.println(Thread.currentThread().getName()+":"+rs.getString("userId"));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
//rs和ps是属于这个连接的,所以连接使用完以后可以直接释放
rs.close();
ps.close();
//conn是属于连接池管理的,此处的close并不会真的关闭此连接,而是将连接返还给连接池
//具体怎么实现的可以参考c3p0的源码,建议大家这样使用
/*很多人使用c3p0获取连接后就不管这些连接了,如果是这样的话,就只能等连接池所有连接用完
 * 连接池主动回收这些连接或者是根据我们设置的参数c3p0.maxIdleTime来回收连接
*/
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("线程池-当前线程花费时间为:"+(endTime-startTime));
}
}

  3)编写连接池ConnectionPool.java

public class ConnectionPool {
private DataSource ds;
private static ConnectionPool pool;
//私有的构造函数
private ConnectionPool(){
ds = new ComboPooledDataSource();
}
public static final ConnectionPool getInstance(){
if(pool == null){
pool = new ConnectionPool();
}
return pool;
}
//获取连接池中的连接
public synchronized final Connection getConnection(){
try {
Connection conn = ds.getConnection();
return conn;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}

  4)c3p0的配置文件

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://10.1.40.61:3306/test_bid_system?useUnicode=true&characterEncoding=utf8
c3p0.user=root
c3p0.password=root
c3p0.initialPoolSize=3
c3p0.minPoolSize=3
c3p0.maxPoolSize=15
c3p0.acquireIncrement=3
c3p0.maxIdleTime=100
c3p0.acquireRetryAttempts=30
c3p0.acquireRetryDelay=1000

  5)运行结果
  以上程序是使用六个线程来连接数据库,使用线程池连接,结果如下:
  这里写图片描述

3.使用静态连接

  1)编写测试类Test.java

public class Test {
private static Connection conn;
public static Connection getConn() {
return conn;
}
public static void setConn(Connection conn) {
Test.conn = conn;
}
public static void main(String[] args) {
initDBConnection();
TestThread[] th = new TestThread[6];
for(int i=0;i<th.length;i++){
th[i] = new TestThread();
}
for(int i=0;i<th.length;i++){
th[i].start();
}
}
private static void initDBConnection() {
String url = "jdbc:mysql://10.1.40.61:3306/test_bid_system?"
+"user=root&password=root&Unicode=true&characterEncoding=UTF8";
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url);
} catch (Exception e) {
e.printStackTrace();
}
}

}

  2)编写线程类TestThread.java

public class TestThread extends Thread{
public void run(){
Statement stmt = null;
ResultSet rs = null;
String sql;
long startTime = System.currentTimeMillis();
try {
stmt = Test.getConn().createStatement();
sql = "select * from bms_weekreport";
rs = stmt.executeQuery(sql);
rs.next();
System.out.println(Thread.currentThread().getName()+":"+rs.getString("userId"));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("采用静态的连接-当前线程花费时间为:"+(endTime-startTime));
}
}

  3)运行结果
  以上程序是使用六个线程来连接数据库,使用静态连接,每次都是使用系统提供好的唯一的连接来访问数据库,使用完不关闭连接,结果如下:
  这里写图片描述

4.使用普通连接方式

  1)编写测试类Test.java

public class Test {
public static void main(String[] args) {
TestThread[] th = new TestThread[6];
for(int i=0;i<th.length;i++){
th[i] = new TestThread();
}
for(int i=0;i<th.length;i++){
th[i].start();
}
}
}

  2)编写线程类TestThread.java

public class TestThread extends Thread{
public void run(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String sql;
String url = "jdbc:mysql://10.1.40.61:3306/test_bid_system?"
+"user=root&password=root&Unicode=true&characterEncoding=UTF8";
long startTime = System.currentTimeMillis();
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url);
stmt = conn.createStatement();
sql = "select * from bms_weekreport";
rs = stmt.executeQuery(sql);
rs.next();
System.out.println(Thread.currentThread().getName()+":"+rs.getString("userId"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
rs.close();
stmt.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("线程池-当前线程花费时间为:"+(endTime-startTime));
}
}

  3)运行结果
  以上程序是使用六个线程来连接数据库,未使用静态连接或者是线程池,每次都是独立地建立和数据库的连接,用完后就关闭,运行结果:
  这里写图片描述

4.结果分析

  我们可以看出,当网站或者服务器访问量不大,客户群比较小的时候采用静态数据库连接是最好的方案;当客户群比较大,采用的静态连接会使某些用户等待较久时间,此时采用线程池比较明智,由于我没有接触过大规模客户群所以此结论也是参考别人的说法列举的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值