1. My idea is to save JDBC connection thread with a linked list. When a connection calls the close method, it also proves that the life of the connection thread is ending, so the connection is recycled through the reflection agent. Add a new connection thread at.
2. When we get the connection to the thread pool, getConnection is OK.
If you don't say much, just go to the code. If you have any knowledge of reflection and proxy, you can see it at a glance. It's a very simple connection pool.
configuration information |
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
user=root
pass=root
driverClassName=com.mysql.jdbc.Driver
public class MyJDBCPool implements DataSource{
private final LinkedList<Connection> connections = new LinkedList<>();
private final Integer numThreads;
public MyJDBCPool(Integer numThreads) {
this.numThreads = numThreads;
this.init();
}
private void init() {
InputStream inputStream = MyJDBCPool.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
try {
properties.load(inputStream);
Class.forName(properties.getProperty("driverClassName"));
for(int i = 0 ;i<this.numThreads;i++){
final Connection conn = DriverManager.getConnection(
properties.getProperty("url"),
properties.getProperty("user"),
properties.getProperty("pass"));
connections.add((Connection) Proxy.newProxyInstance(
MyJDBCPool.class.getClassLoader(),
new Class[] { Connection.class },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (!method.getName().equals("close")) {
return method.invoke(conn, args);
}
System.out.println("Another connection is finished,Return connection pools,The current connection pool has"
+ connections.size() + "Connection objects");
return null;
}
}));
System.out.println("Line connection pool added a link object,The current connection pool has======"
+ connections.size() + "=====Connection objects");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public Connection getConnection() throws SQLException {
Connection conn = null;
if (connections.size() > 0) {
conn = connections.removeFirst();
System.out.println("There is a connection object occupied,The connection pool also has=========" + connections.size()
+ "A connection");
}
return conn;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
public class MyJDBCTest {
public static void main(String[] args) throws SQLException {
DataSource dataPool = new MyJDBCPool(10);
for(int i =0 ;i<5;i++){
dataPool.getConnection();
}
Connection conn = dataPool.getConnection();
conn.close();
dataPool.getConnection();
dataPool.getConnection();
}
}
After we had getConnection six times before, there are four connection objects left. At this time, one is close d and recycled by the agent, so there are five connections available.