1、DBConnection.java
package com.db1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnection {
private static String drivers = DBConfig.DRIVERS;
private static String url = DBConfig.URL;
private static String user = DBConfig.USER;
private static String password = DBConfig.PASSWORD;
public static Connection GetConnection() { // 获取数据连接
Connection conn = null;
try {
Class.forName(drivers).newInstance();
//
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
System.out.println("url------"+url);
System.out.println("user------"+user);
System.out.println("password------"+password);
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return conn;
}
public static void close(Connection conn)
{
try {
if(conn != null && !conn.isClosed())
{
conn.close();
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
/*
* 关闭连接
*/
2、Utils.java
package com.my.datasource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Utils {
private static String drivers = DBConfig.DRIVERS;
private static String url = DBConfig.URL;
private static String user = DBConfig.USER;
private static String password = DBConfig.PASSWORD;
public static Connection GetConnection() { // 获取数据连接
Connection conn = null;
try {
Class.forName(drivers).newInstance();
//
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
System.out.println("url------"+url);
System.out.println("user------"+user);
System.out.println("password------"+password);
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return conn;
}
public static void close(Connection conn)
{
try {
if(conn != null && !conn.isClosed())
{
conn.close();
}
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
3、DBConfig.java
package com.db1;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DBConfig {
private static String db_config = "F:\\EclipseSpace\\EclipseSpace\\DBTest00\\src\\com\\db1\\dbconfig.properties";
public static String DRIVERS = null;
public static String URL = null;
public static String USER = null;
public static String PASSWORD = null;
static //声明静态代码块
{
Properties props = new Properties();
InputStream ips = null;
try {
//读取属性文件
ips = new FileInputStream(db_config);
props.load(ips);
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
DRIVERS = props.getProperty("drivers");
URL = props.getProperty("url");
USER = props.getProperty("user");
PASSWORD = props.getProperty("pwd");
}
}
4、MyDataSource.java
package com.my.datasource;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 自定义连接池
* @author Administrator
*
*/
public class MyDataSource {
//定义一个池,用于存放连接
private static List<Connection> pool = Collections.synchronizedList(new ArrayList<>());
//使用静态代码块给池中加入连接
static {
for(int i = 0; i < 10; i++) {
Connection conn = Utils.GetConnection();
pool.add(conn);
}
}
/**
* 获取一个连接
* @return
*/
public static Connection removeConnection() {
Connection conn = pool.remove(0);
//创建代理对象
Connection proxyConn = (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO 自动生成的方法存根
Object rtValue = null;
if("close".equals(method.getName())) {
//还回池中
pool.add(conn);
}
else {
rtValue = method.invoke(conn, args);
}
return rtValue;
}
});
return proxyConn;
}
// 获取池中的连接数
public static int getPoolSize() {
return pool.size();
}
}
5、 Test.java
package com.my.datasource;
import java.sql.Connection;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) throws SQLException {
// TODO 自动生成的方法存根
int size = MyDataSource.getPoolSize();
System.out.println("使用连接之前" + size);
for(int i = 0; i < 10; i ++) {
Connection conn = MyDataSource.removeConnection();
System.out.println(conn);
try {
//不应该关闭,应放入池中。
conn.close();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
int size1 = MyDataSource.getPoolSize();
System.out.println("使用连接之后" + size1);
}
}
6、结果
二、加线程的 数据库连接池
package com.my.datapool;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.concurrent.TimeUnit;
public class ConnectionDriver {
static class ConnectionHandler implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("commit")) {
TimeUnit.MILLISECONDS.sleep(100);
}
return null;
}
}
//创建Connection得代理,在commit时候休眠100
public static final Connection createConnection() {
return (Connection) Proxy.newProxyInstance(ConnectionDriver.class.getClassLoader(), new Class<?>[] {Connection.class}, new ConnectionHandler());
}
}
package com.my.datapool;
import java.sql.Connection;
import java.util.LinkedList;
public class ConnectionPool {
private LinkedList<Connection> pool = new LinkedList<>();
public ConnectionPool(int initialSize) {
if(initialSize > 0) {
for(int i = 0; i < initialSize; i++) {
pool.addLast(ConnectionDriver.createConnection());
}
}
}
public void releaseConnection(Connection connection) {
if(connection != null) {
synchronized (pool) {
// 连接释放后进行通知
pool.addLast(connection);
pool.notifyAll();
}
}
}
// mills 内无法获取到链接,将会返回null
public Connection fetchConnection(long mills) throws InterruptedException {
synchronized (pool) {
// 完全超时
if(mills <= 0) {
while(pool.isEmpty()) {
pool.wait();
}
return pool.removeFirst();
} else {
long future = System.currentTimeMillis() + mills;
long remaining = mills;
while(pool.isEmpty() && remaining > 0) {
pool.wait(remaining);
remaining = future - System.currentTimeMillis();
}
Connection result = null;
if( !pool.isEmpty()) {
result = pool.removeFirst();
}
return result;
}
}
}
}
package com.my.datapool;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionPoolTest {
static ConnectionPool pool = new ConnectionPool(10);
//保证所有得ConnectionRunner 能够同时开始
static CountDownLatch start = new CountDownLatch(1);
//main线程会等待所有ConnectionRunner结束后才能继续执行
static CountDownLatch end;
public static void main(String[] args) {
// 线程数量,可以修改数量进行观察
int threadCount = 10;
end = new CountDownLatch(threadCount);
int count = 20;
AtomicInteger got = new AtomicInteger();
AtomicInteger notGot = new AtomicInteger();
for(int i = 0; i < threadCount; i++) {
Thread thread = new Thread(new ConnectionRunner(count,got,notGot),
"connectionRunnerThread");
thread.start();
}
start.countDown();
try {
end.await();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println("total invoke:" + (threadCount * count ));
System.out.println("got Connection: " + got);
System.out.println("not got Connection: " + notGot);
}
static class ConnectionRunner implements Runnable{
int count;
AtomicInteger got;
AtomicInteger notGot;
public ConnectionRunner(int count, AtomicInteger got,AtomicInteger notGot) {
this.count = count;
this.got = got;
this.notGot = notGot;
}
public void run() {
try {
start.await();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
while(count > 0) {
//从线程池获取连接,1000ms内无法获取到,返回null
//分别统计连接获取得数量got和未获取到的数量notGot
try {
Connection connection = pool.fetchConnection(1000);
if(connection != null) {
try {
connection.createStatement();
connection.commit();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}finally {
pool.releaseConnection(connection);
got.incrementAndGet();
}
} else {
notGot.incrementAndGet();
}
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} finally {
count --;
}
}
end.countDown();
}
}
}