使用java模拟简易的数据库连接池并对连接池进行多线程的调用 要求: 1、要求程序可以自动运行,应用后端没有实际的数据库,程序自动输出应用的链接状态; 2、编写单元测试模块并使用多线程模拟并发调用该连接池。
时间: 2024-05-11 22:17:11 浏览: 94
好的,我可以回答你的问题。首先,你需要理解什么是数据库连接池。数据库连接池是一种维护数据库连接的技术,它可以在应用程序启动时创建一些连接,然后在需要连接数据库时从连接池中获取一个连接,使用完后再将连接归还到连接池中。这种技术可以避免频繁创建和销毁连接带来的性能损耗,提高应用程序的性能。
以下是一个简单的 Java 实现数据库连接池的代码,可以帮助你理解连接池的实现:
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class ConnectionPool {
private static final String DB_URL = "jdbc:mysql://localhost:3306/test";
private static final String USER = "root";
private static final String PASSWORD = "123456";
private static final int INIT_SIZE = 5;
private static final int MAX_SIZE = 10;
private List<Connection> pool;
public ConnectionPool() {
pool = new ArrayList<>(INIT_SIZE);
for (int i = 0; i < INIT_SIZE; i++) {
pool.add(createConnection());
}
}
private Connection createConnection() {
try {
return DriverManager.getConnection(DB_URL, USER, PASSWORD);
} catch (SQLException e) {
throw new RuntimeException("Unable to create a new connection.", e);
}
}
public Connection getConnection() {
if (pool.isEmpty()) {
if (pool.size() < MAX_SIZE) {
pool.add(createConnection());
} else {
throw new RuntimeException("The connection pool is full.");
}
}
Connection connection = pool.remove(0);
return connection;
}
public void releaseConnection(Connection connection) {
if (pool.size() < INIT_SIZE) {
pool.add(connection);
} else {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException("Unable to close the connection.", e);
}
}
}
}
```
在这个实现中,我们使用了一个 List 来维护连接池中的连接对象。在初始化时,我们创建了一些连接,然后在需要连接数据库时从连接池中获取连接,使用完后再将连接归还到连接池中。当连接池中没有可用的连接时,我们可以选择等待或者抛出异常。
接下来,我们可以编写一个简单的单元测试模块,并使用多线程模拟并发调用该连接池:
```java
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Random;
public class ConnectionPoolTest {
private ConnectionPool connectionPool = new ConnectionPool();
@Test
public void test() throws InterruptedException {
int threadCount = 10;
Thread[] threads = new Thread[threadCount];
for (int i = 0; i < threadCount; i++) {
threads[i] = new Thread(new Worker(), "Thread-" + (i + 1));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
}
private class Worker implements Runnable {
private Random random = new Random();
@Override
public void run() {
Connection connection = connectionPool.getConnection();
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM user WHERE id = ?");
statement.setInt(1, random.nextInt(100));
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
System.out.println(Thread.currentThread().getName() + ": " + resultSet.getInt("id") + " " + resultSet.getString("name"));
}
} catch (SQLException e) {
throw new RuntimeException("Unable to execute the SQL statement.", e);
} finally {
connectionPool.releaseConnection(connection);
}
}
}
}
```
在这个单元测试模块中,我们创建了多个线程,并在每个线程中获取连接池中的连接,并执行一些 SQL 查询操作。我们使用了一个随机数生成器来生成查询语句中的参数,以模拟多个线程同时访问数据库的情况。
当我们运行这个单元测试模块时,我们会看到多个线程同时访问数据库,并输出查询结果。同时,我们也可以观察到连接池的状态,以确保连接池的运行状态。
阅读全文