我在主服务器机器上运行了H2服务器进程,允许TCP连接.
假设我想执行100个SQL查询:
SELECT * FROM TEST
而且,出于我自己的目的,我想每个线程做一个查询.让我们在一个且只有一个在线程之间共享的Connection对象中执行此操作:
>创建一个Connection对象.
>创建100个主题.
>在每个线程中,使用共享Connection对象来调用SQL查询.
以上将有效,但会有点慢.当然,毕竟,如果有人使用Connection,那么其他人必须等待它.
那么,让我们为每个线程建立一个连接:
>创建100个主题.
>在每个线程中,创建一个新的Connection对象并调用SQL查询.
更快,更快.但我觉得100连接有点浪费.也许50个连接就可以了.我听说我可以使用JdbcConnectionPool来做这种事情.
>创建一个最多包含50个连接的JdbcConnectionPool.
>创建100个主题.
>在每个线程中,使用pool.getConnection()然后调用SQL查询.
呵呵.这很慢.如果有的话,它和第一种方法一样慢.也许,出于好奇,我应该将连接的最大值设置为100 ……
……而且还很慢.奇怪的.我的理解是,具有100个连接的池相当于为我的100个线程中的每个线程建立一个连接.
可能是什么问题?这是最后一次测试的代码:
import java.sql.Connection;
import java.sql.ResultSet;
import org.h2.jdbcx.JdbcConnectionPool;
public class App {
public static void main(String[] args) throws Exception {
Class.forName("org.h2.Driver");
JdbcConnectionPool pool = JdbcConnectionPool.create("url", "user", "password");
pool.setMaxConnections(100);
for (int i = 0; i < 100; ++i) {
Thread t = new Thread(new Client(i, pool));
t.start();
}
}
}
class Client implements Runnable {
int id;
JdbcConnectionPool pool;
public Client(int id, JdbcConnectionPool pool) {
this.id = id;
this.pool = pool;
}
public void run() {
try {
Connection conn = pool.getConnection();
ResultSet set = conn.createStatement().executeQuery("SELECT * FROM TEST");
if (set.next()) {
System.out.println("Finished " + id);
}
set.close();
conn.close();
}catch (Exception e) {
}
}
}
我正在使用H2 1.4.182.
最佳答案 JdbcConnectionPool的源代码#getConnection():
public Connection getConnection() throws SQLException {
long max = System.currentTimeMillis() + timeout * 1000;
do {
synchronized (this){
if (activeConnections < maxConnections) {
return getConnectionNow();
}
try {
wait(1000);
} catch (InterruptedException e) {
// ignore
}
}
} while (System.currentTimeMillis() <= max);
throw new SQLException("Login timeout", "08001", 8001);
}
您示例中最昂贵的操作之一是创建连接.正如您所看到的,方法getConnection()具有锁定同步(this),因此只有一个线程可以同时创建连接,并且所有其他线程都在等待.
我相信内置的h2连接池非常简单.如果您想拥有高性能连接池,可以查看C3P0或BoneCP.