1,我的思想是,用一个链表对JDBC连接线程进行保存。这个链表中保存在执行的连接,当一个连接调用close方法的时候,也就证明此连接线程的生命正在走向终结,就将这个连接通过反射代理回收。在添加新的连接线程。
2,我们往线程池中获取连接的时候,getConnection就OK了。
话不多说,直接上代码,对于反射和代理有过了解的,一看代码就明白,写的一个很简陋的连接池。
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("又一个连接用玩完了,返回个连接池,当前连接池有"
+ connections.size() + "个连接对象");
return null;
}
}));
System.out.println("线连接池添加了一个链接对象,当前连接池有======"
+ connections.size() + "=====个连接对象");
}
} 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("有一个连接对象被占用,连接池还有=========" + connections.size()
+ "个连接");
}
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();
}
}
我们在之前有了6次getConnection之后,还剩了4个连接对象,此时close一个,被代理回收了,所以还剩5个连接可用。